调用约定和评估顺序

5 c++ arguments function

我知道C++没有指定参数传递给函数的顺序.但是如果我们编写以下代码:

void __cdecl func(int a, int b, int c)
{
       printf("%d,%d,%d", a,b,c);
}
int main()
{
   int i=10;
   func(++i, i, ++i);
}
Run Code Online (Sandbox Code Playgroud)

我们能否可靠地说输出是12,11,11因为__cdecl确保参数传递顺序是从右到左?

Naw*_*waz 13

根据标准,您需要了解和区分两件事:

  1. C++没有指定参数传递给函数的顺序(就像你自己说的那样,这是真的!)

  2. C++没有指定函数参数的计算顺序[expr.call].

现在,请注意,__cdecl只确保第一个,而不是第二个.调用约定 决定函数参数的传递方式,left-to-right或者right-to-left; 他们仍然可以按任何顺序进行评估!

希望这能澄清您对呼叫惯例的疑虑.

但是,由于这些约定是Microsoft编译器对C++的扩展,因此您的代码是不可移植的.在这种情况下,您可以看到MSVC++编译器如何评估函数参数并放松,如果您不想在其他平台上运行相同的代码!


func(++i, i, ++i);
Run Code Online (Sandbox Code Playgroud)

请注意,此特定代码会调用未定义的行为,因为i它会多次递增不会干扰任何序列点.