调用约定和评估秩序 [英] calling convention and evaluation order
问题描述
我知道,C ++不指定哪些参数传递给函数的顺序。但是,如果我们编写以下code:
无效__cdecl FUNC(INT A,INT B,INT C)
{
的printf(%D,%D,%D,A,B,C);
}
诠释的main()
{
INT I = 10;
FUNC(++我,我,我++);
}
我们可以肯定地说,输出将 12,11,11
自的 __ CDECL 确保参数传递顺序是从右到左?
按照标准,有两件事情你需要理解和区分:
- C ++不指定哪些参数的通过以一个订单
功能(像你说的你自己,
是真的!)
- C ++不指定该函数的参数是顺序
评估 [expr.call]。
块引用>现在,请注意,
__ CDECL
既保证了第一,没有第二个。 调用约定决定的仅如何在函数的参数能否通过,左到右
或从右至左
; 他们仍然可以以任意顺序评价过!希望这澄清了有关调用约定你的疑惑。
然而,由于这些公约都是微软编译器扩展到C ++,所以你的code是不可移植。在这种情况下,你可以看到MSVC ++编译器如何评估函数的参数,并放宽如果你不想上运行其他平台一样code!
FUNC(++我,我,我++);
请注意,这个特殊的code调用不确定的行为,因为
I
递增一次以上的没有的任何干预的任何序列点。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); }
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++ doesn't specify the order in which parameters are passed to a function (as you said yourself, that is true!)
- C++ doesn't specify the order in which the function arguments are evaluated [expr.call].
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
orright-to-left
; they can still be evaluated in ANY order!Hope this clarifies your doubts regarding the calling conventions.
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);
Note that this particular code invokes undefined behavior, because
i
is incremented more than once without any intervening any sequence point.这篇关于调用约定和评估秩序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!