我正在查看我的一门老课程,发现以下内容:
int main(void) {
int x = 0;
return (x = 1) + (x = 2);
}
“根据C标准,上面程序的行为是不确定的。
GCC4,MSVC:返回4
GCC3,ICC和Clang:返回3英寸
在这之后有一张幻灯片说下面的代码在C标准中不是未定义的。谁能向我解释为什么这不是不确定的行为?
int main(void) {
int x = 0;
int y = 2;
return (x = 4) + (x=(x + y)/2);
}
答案 0 :(得分:3)
C规范的相关段落:
给出任意两个求值A和B,如果A在B之前排序,则A的执行应在B执行之前。(相反,如果A在B之前排序,则B在A之后排序。)如果A在B之前或之后没有排序,则A和B都没有排序。
和
如果相对于相同标量对象上的不同副作用或使用相同标量对象的值进行的值计算,相对于标量对象的副作用未排序,则行为不确定。如果一个表达式的子表达式有多个允许的排序,则如果在任何排序中都出现这种无序的副作用,则行为是不确定的。
因此,您问题中的两个代码片段均会调用未定义的行为。
(因为最初的第二个片段是C ++,所以值得一提的是,即使最新版本的C ++扩展了“先后顺序”和“后继顺序”的含义,但AFAIK仍然不包含{{1} }作为序列点。)