代码之家  ›  专栏  ›  技术社区  ›  sum1stolemyname

后增量运算符的评估是按什么顺序进行的?

  •  3
  • sum1stolemyname  · 技术社区  · 15 年前

    鉴于

    std::vector<CMyClass> objects;
    CMyClass list[MAX_OBJECT_COUNT];
    

    这样做明智吗?

    for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i++));
    

    或者我应该把循环扩展到这个?

    for(unsigned int i = 0; i < objects.size(); i++)
    {
      list[i] = objects.at(i);
    }
    
    4 回复  |  直到 15 年前
        1
  •  11
  •   Steve Jessop    15 年前

    前者是未定义的行为。没有具体说明 list[i] 在函数调用之前或之后对 objects.at .

    因此,对表达式的各个部分进行了合法的排序,其中 i 被访问(在)中 表[我] )并单独修改(in i++ ,没有中间的序列点。

    这正是C++标准中未定义行为的条件——是否存在这样的法律排序。IIRC C标准的表述略有不同,但效果相同。

    如果有疑问,不要编写使用递增运算符的表达式,也不要在表达式中的任何其他地方使用相同的值。你可以用逗号运算符( i++, i++ 和条件运算符( i ? i++ : i-- 很好),因为它们有序列点,但很少值得。 || && 同样的,还有 p != end_p && *(p++) = something; 不是完全不可信。任何其他用途,如果你盯着它看足够长的时间,你通常可以制定出一个评估顺序,把事情搞砸了。

    除了复杂的可理解性之外 for 表达式和 对于 空体环。

        2
  •  6
  •   kennytm    15 年前

    如果有疑问,请选择更容易理解的形式(扩展循环)。

    (我想 list[i] = objects.at(i++) 导致未定义的行为。)

        3
  •  1
  •   Michael Kristofik    15 年前

    引用 i 在同一表达式中 i++ 可能是未定义的行为。但既然你用的是容器,你能不能写下…

    list = objects;                               // if they're the same type
    list.assign(objects.begin(), objects.end());  // if not
    
        4
  •  1
  •   Raphaël Saint-Pierre    15 年前

    正如前面所说,在使用变量的同一表达式中对变量进行后递增会产生未定义的行为。 但是,如果您希望保持紧凑的形式,您可以引入一个序列点并继续

    for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++);