c - 为什么 gcc 不将逗号视为序列点?

标签 c gcc clang

我正在观察关于我认为是 clanggcc 之间的 C 标准的一部分的不同行为(我的 mac 或 linux 上的自制版本)。问题是参数列表中的逗号是否是序列点。 clang 会这样解释它,但 gcc 不会。

这段代码演示了这个问题:

#include <stdio.h>

int inner(int *v) {
  *v += 1;
  return 1;
}

int outer(int x, int y) {
  return y;
}

int main(int argc, char *argv[]) {
  int x = 4;
  printf ("result=%d\n", outer(inner(&x), x));
}

结果:

$ clang -o comseq comseq.c && ./comseq
result=5
$ gcc-4.8 -o comseq comseq.c && ./comseq
result=4
$ gcc-5 -o comseq comseq.c && ./comseq
result=4

目前我无法访问 C 标准的副本,但在看到 gcc 之前,我非常确定 clang 的行为是正确的的解释。使用 --std= 选项根本没有改变我的结果。

预计到达时间

在更好的阅读中,这个问题确实在 https://stackoverflow.com/a/4176333/3171657 中得到了回答。 :

a , b (§5.18) (in func(a,a++) , is not a comma operator, it's merely a separator between the arguments a and a++. The behaviour is undefined in that case if a is considered to be a primitive type)

但这虽然非常有用,但却是一个很长的答案,所以也许留下这个问题会对像我这样的其他用户有所帮助。另外,迂腐地说,这个问题是关于 C++,而不是 C。

最佳答案

参数列表中的逗号不是序列点——它们不是术语意义上的逗号运算符。

标准 (ISO/IEC 9899:2011) 关于函数调用的部分 (§6.5.2.2) 说:

¶3 A postfix expression followed by parentheses () containing a possibly empty, comma- separated list of expressions is a function call. The postfix expression denotes the called function. The list of expressions specifies the arguments to the function.

¶4 An argument may be an expression of any complete object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.

¶10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

(我省略了几个脚注,但内容与讨论无关。)

没有关于以任何特定顺序计算的表达式。

另请注意,逗号运算符会产生单个值。如果你解释:

function(x, y)

由于具有逗号运算符,该函数将只有一个参数 — y 的值。当然,这不是函数的工作方式。如果你想要一个逗号运算符,你必须使用额外的括号:

function((x, y))

现在 function() 被调用一个单一的值,它是 y 的值,但它是在 x 被计算之后计算的.这种表示法很少使用,尤其是因为它可能会使人感到困惑。

关于c - 为什么 gcc 不将逗号视为序列点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34476866/

相关文章:

c - 如何使用套接字传输pdf、mp3或mp4文件?

c - C 中的类型转换,大问题

c++ - 带有 C++ 模板的虚假 "use of local variable with automatic storage from containing function"?

c - setjmp 和 GCC 的合法使用

c - 编译时出错,collect2 : cannot find ld

clang - 在 Ubuntu 上使用 Clang 3.0 编译 libc++ 时出错

c - 有没有一种简单的方法可以获取最后 x 分钟的成功读取百分比?

CFNumberFormatterCreateStringWithNumber int 问题

C++ 模板定义在 clang 上失败,适用于 GCC

c++ - 如何在 -std=c++11 -Weverything -Werror 中使用 clang++