函数参数中的逗号运算符

Kar*_*uil 0 c expression arguments comma-operator

我正在阅读 GNU C 手册的摘录:

\n\n
\n

您可以使用逗号运算符来分隔两个(表面上相关的)表达式。

\n
\n\n

稍后在描述中:

\n\n
\n

如果要在函数参数中使用逗号运算符,则需要在其两侧加上括号。\xe2\x80\x99s 因为函数参数列表中的逗号具有不同的含义:它们分隔参数。

\n
\n\n

到现在为止,一切都还好。奇怪的部分是:

\n\n
\n

foo (x, (y=47, x), z);是一个只有三个参数的函数调用。(第二个参数是(y=47, x)。)

\n
\n\n

问题是:参数如何压入堆栈,如何从函数内部访问它?

\n

Sou*_*osh 5

就你而言,

\n\n
  foo (x, (y=47, x), z);\n
Run Code Online (Sandbox Code Playgroud)\n\n

功能上类似于

\n\n
  foo (x, x, z);\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据逗号运算符的属性,先计算左侧操作数并丢弃结果,然后计算右侧操作数,这就是结果。

\n\n

为了完整起见,引用C11章节 \xc2\xa76.5.17

\n\n
\n

逗号运算符的左操作数被计算为 void 表达式;它的求值与右操作数的求值之间有一个序列点。然后计算右操作数;结果有其类型和值。

\n
\n\n

需要注意的是:变量将被更新,因为 LHS 操作数被计算为 void 表达式,但对此函数调用y没有影响。如果是全局变量并在函数中使用,它将看到初始值。yfoo()47

\n\n

也就是说,要回答

\n\n
\n

参数如何压入堆栈

\n
\n\n

非常依赖于实现(架构)。C 没有指定函数参数传递的任何顺序,并且某些体系结构可能根本不使用“堆栈”进行函数参数传递!

\n

  • 将 y 设置为 47 会产生副作用,这可能是全局范围的。 (6认同)