调用约定和求值顺序 [英] calling convention and evaluation order
问题描述
我知道 C++ 没有指定参数传递给函数的顺序.但是如果我们写如下代码:
I know that C++ doesn't specify the order in which parameters are passed to a function. But if we write the following code:
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);
}
我们能否可靠地说输出将是 12,11,11
,因为 __cdecl 确保参数传递顺序是从右到左?
Can we reliably say the output would be 12,11,11
since the __cdecl ensures that argument-passing order is right to left?
推荐答案
根据标准,您需要了解和区分两件事:
As per the Standard, there are two things you need to understand and differentiate:
C++ 没有指定参数传递到函数(正如你自己所说,这是真的!)
C++ doesn't specify the order in which parameters are passed to a function (as you said yourself, that is true!)
C++ 没有指定函数参数的求值顺序 [expr.call].
C++ doesn't specify the order in which the function arguments are evaluated [expr.call].
现在,请注意,__cdecl
只确保第一个,而不是第二个.调用约定决定仅函数的方式参数将被传递,left-to-right
或 right-to-left
;它们仍然可以按任何顺序进行评估!
Now, please note, __cdecl
ensures only the first, not the second. Calling conventions decide only how the functions arguments will be passed, left-to-right
or right-to-left
; they can still be evaluated in ANY order!
希望这能澄清您对调用约定的疑虑.
Hope this clarifies your doubts regarding the calling conventions.
但是,由于这些约定是 Microsoft 编译器对 C++ 的扩展,因此您的代码是不可移植的.在这种情况下,您可以看到 MSVC++ 编译器如何评估函数参数并放松如果您不想在其他平台上运行相同的代码!
However, since these conventions are Microsoft compiler extension to C++, so your code is non-portable. In that case, you can see how MSVC++ compiler evaluates function arguments and be relax IF you don't want to run the same code on other platform!
func(++i, i, ++i);
请注意,此特定代码会调用未定义的行为,因为 i
增加了不止一次 任何干预任何序列点.
Note that this particular code invokes undefined behavior, because i
is incremented more than once without any intervening any sequence point.
这篇关于调用约定和求值顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!