C++中变量的多个预增量运算(C?)

Jat*_*tin 17 c c++ operators operator-precedence pre-increment

为什么以下用C++编译?

int phew = 53;
++++++++++phew ;
Run Code Online (Sandbox Code Playgroud)

相同的代码在C中失败,为什么?

Joh*_*itb 29

注意:DR#637DR#222这两个缺陷报告对于理解以下行为原理非常重要.


为了解释,在C++ 0x中有value computationsside effects.例如,副作用是分配,并且值计算是确定左值引用的内容或从左值中读取值.请注意,C++ 0x不再具有序列点,这些内容的措辞是"在之前排序"/"在之后排序".并且有人说

如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义.

++v相当于v += 1等价于v = v + 1(除了v只评估一次).这将产生++ (v = v + 1)我将写作inc = inc + 1,其中inc指的是左值结果v = v + 1.

在C++中,0x ++ ++v不是未定义的行为,因为对于a = b赋值在b和a的值计算之后,但在赋值表达式的值计算之前进行了排序.因此,在v = v + 1计算值之前对asignment进行排序inc.并且inc = inc + 1在值计算之后对赋值进行排序inc.最后,两个分配将按顺序排序,并且没有未定义的行为.

  • 好答案.同样`int a = 4; ++ a = 5;`不会在C++ 0x中调用UB,对吗? (3认同)
  • @Johannes:我不明白为什么`a = ++ a`不会调用未定义的行为,但是`a = a ++`会这样做.发生了什么"除非另有说明,个别经营者的操作数和个别表达的子表达式的评价顺序,以及副作用的发生顺序,都未指明"? (3认同)
  • @Daniel,第二个确实会调用未定义的行为,因为对"a ++"中的a的修改之前没有排序,但是*之后*是"a ++"的值计算(当然,因为你希望它产生旧的值).因此,"a ++"中的赋值和修改不是相对于彼此排序的.您引用的文字现在的措辞为"除非另有说明,否则对个体操作员的操作数和个别表达式的子表达式的评估是不合理的." (3认同)
  • @Prasoon,对"a ++"中a的修改在"a ++"的值计算之后进行排序."a + a ++"中的两个a不以任何方式排序,既不是它们的值计算,也不是它们的副作用.所以你有一个副作用(对a的修改)相对于a(第一个操作数)的值计算没有顺序,所以你有UB. (3认同)

Pra*_*rav 14

这是因为在C++预增量运算符中返回 a lvalue并且它要求其操作数为a lvalue.

++++++++++phew ; 在解释为 ++(++(++(++(++phew))))

但是,您的代码会调用,Undefined Behaviour因为您尝试phew在两个序列点之间修改多次值.

C,预增量运算符返回一个rvalue并要求其操作数为lvalue.所以你的代码不能在C模式下编译.

  • 这只是C++ 03中的UB.它在C++ 0x中有效. (8认同)
  • @Merlyn Morgan-Graham:阅读Steve Summit撰写的这篇文章:http://c-faq.com/expr/seqpoints.html. (3认同)
  • @Prasoon:不要再猜你,我只是好奇地读到你所说的话; "你试图在两个序列点之间多次修改phew的值".您能否为标准的这一部分提供注释,以便我可以阅读更多相关信息? (2认同)
  • 为了清楚起见,`++++ i`是用户定义类型的明确定义,对吧? (2认同)
  • @FredOverflow:是因为函数调用引入了一个序列点.:) (2认同)