为什么GCC和Clang的结果与以下代码不同?

0 c gcc llvm

对于以下使用gcc和clang的代码,我得到了不同的结果,我相信这不是一个严重的错误,但是我想知道哪个结果与标准更一致?非常感谢您的回复。

我使用gcc(Ubuntu 7.3.0-27ubuntu1〜18.04)7.3.0和clang版本6.0.0-1ubuntu2(tags / RELEASE_600 / final)

#include <stdio.h>
int get_1(){
        printf("get_1\n");
        return 1;
}
int get_2(){
        printf("get_2\n");
        return 2;
}
int get_3(){
        printf("get_3\n");
        return 3;
}
int get_4(){
        printf("get_4\n");
        return 4;
}
int main(int argc, char *argv[])
{
        printf("%d\n",get_1() + get_2() - (get_3(), get_4()));
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc的结果是

get_3
get_1
get_2
get_4
-1
Run Code Online (Sandbox Code Playgroud)

of的结果是

get_1
get_2
get_3
get_4
-1
Run Code Online (Sandbox Code Playgroud)

ali*_*oar 8

C在评估某些运算符的操作数时不施加顺序。在C标准中,评估顺序是由顺序点决定的。当存在序列点时,该语言的良好实现必须先评估序列点左侧的所有内容,然后才能开始评估右侧的内容。在+-运营商不包含任何序列点。这是5.1.2.3 p2的定义

在执行序列中某些特定的点(称为顺序点)上,以前评估的所有副作用都应完整,并且以后评估的副作用都不应发生。

在你的表情

get_1() + get_2() - (get_3(), get_4())
Run Code Online (Sandbox Code Playgroud)

你有+-和逗号,操作。只有逗号强加了一个评估顺序,+-不是。


Col*_*lin 5

,之间get_3()get_4()是唯一的序列点printf("%d\n",get_1() + get_2() - (get_3(), get_4()));get_x呼叫可以在编译器中定义的任何顺序发生,只要get_3()之前发生get_4()

您正在看到未指定行为的结果。

  • 这不是未定义的行为,而是未指定的行为。 (2认同)