当前位置:  开发笔记 > 运维 > 正文

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

如何解决《为什么gcc不将逗号视为序列点?》经验,为你挑选了1个好方法。

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

此代码演示了此问题:

#include 

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标准的副本,但clang在我看到gcc解释之前,我非常确定这种行为是正确的.使用该--std=选项并没有改变我的结果.

ETA

在更好的阅读中,确实可以在/sf/ask/17360801/中回答这个问题:

a,b(§5.18)(在func(a,a ++)中)不是逗号运算符,它只是参数a和a ++之间的分隔符.在这种情况下,如果a被认为是基本类型,则行为是未定义的)

但是,虽然非常有用,但这是一个很长的答案,所以也许留下这个问题将有助于像我这样的其他用户.另外,要迂腐,那个问题是关于C++,而不是C.



1> Jonathan Lef..:

参数列表中的逗号不是序列点 - 它们不是术语含义内的逗号运算符.

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

3后缀表达式后跟()包含可能为空的逗号分隔表达式列表的括号是一个函数调用.后缀表达式表示被调用的函数.表达式列表指定函数的参数.

4参数可以是任何完整对象类型的表达式.在准备对函数的调用时,将评估参数,并为每个参数分配相应参数的值.

...

10在评估函数指示符和实际参数之后但在实际调用之前有一个序列点.调用函数(包括其他函数调用)中的每个评估(在执行被调用函数的主体之前或之后没有特别排序)对于被调用函数的执行是不确定地排序的.

(我省略了几个脚注,但内容与讨论没有密切关系.)

没有任何关于在任何特定序列中评估的表达式.

另请注意,逗号运算符会生成单个值.如果您解释:

function(x, y)

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

function((x, y))

现在function()使用单个值调用,该值是值y,但是在评估之后x评估.这种符号很少使用,尤其是因为它可能会让人感到困惑.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有