我正在观察不同的行为,我认为它是C标准的一部分clang和gcc(在我的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));
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
$ 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
Run Code Online (Sandbox Code Playgroud)
我目前无法访问C标准的副本,但clang在我看到gcc解释之前,我非常确定这种行为是正确的.使用该--std=选项并没有改变我的结果.
ETA
在更好的阅读中,确实可以在/sf/answers/292343341/中回答这个问题:
a,b(§5.18)(在func(a,a ++)中)不是逗号运算符,它只是参数a和a ++之间的分隔符.在这种情况下,如果a被认为是基本类型,则行为是未定义的)
但是,虽然非常有用,但这是一个很长的答案,所以也许留下这个问题将有助于像我这样的其他用户.另外,要迂腐,那个问题是关于C++,而不是C.
参数列表中的逗号不是序列点 - 它们不是术语含义内的逗号运算符.
关于函数调用的标准部分(ISO/IEC 9899:2011)(第6.5.2.2节)说:
3后缀表达式后跟
()包含可能为空的逗号分隔表达式列表的括号是一个函数调用.后缀表达式表示被调用的函数.表达式列表指定函数的参数.4参数可以是任何完整对象类型的表达式.在准备对函数的调用时,将评估参数,并为每个参数分配相应参数的值.
...
10在评估函数指示符和实际参数之后但在实际调用之前有一个序列点.调用函数(包括其他函数调用)中的每个评估(在执行被调用函数的主体之前或之后没有特别排序)对于被调用函数的执行是不确定地排序的.
(我省略了几个脚注,但内容与讨论没有密切关系.)
没有任何关于在任何特定序列中评估的表达式.
另请注意,逗号运算符会生成单个值.如果您解释:
function(x, y)
Run Code Online (Sandbox Code Playgroud)
由于有一个逗号运算符,该函数只有一个参数 - 值为y.当然,这不是功能的工作方式.如果你想要一个逗号运算符,你必须使用额外的括号:
function((x, y))
Run Code Online (Sandbox Code Playgroud)
现在function()使用单个值调用,该值是值y,但是在评估之后x评估.这种符号很少使用,尤其是因为它可能会让人感到困惑.
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |