解释printf中的评估顺序

jav*_*ava 5 c printf

main()
{
    int i=5;
    printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
}
Run Code Online (Sandbox Code Playgroud)

输出是45545,但我不知道它是如何工作的.有人说函数调用中的参数从左到右被压入堆栈.

Mak*_*zin 19

未指定函数参数的评估顺序.

从c99标准:

6.5.2.2函数调用

10 /函数指示符的评估顺序,实际参数和实际参数中的子表达式是未指定的,但在实际调用之前有一个序列点.

然而,这只是问题的一部分.另一件事(实际上更糟糕,因为它涉及未定义的行为)是:

6.5表达式

2 /在上一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次.此外,先前的值应该只读以确定要存储的值.

在我们的例子中,所有参数评估仅在2个序列点之间:;输入函数之前和之前的点,但是在评估了所有参数之后.你最好不要写这样的代码.

在某些地方,C标准相当宽松,为编译器可能做的优化留出了空间.

  • 您可能应该添加一个原因,为什么它未定义(优化) (3认同)

Raj*_*Raj 5

标准中没有定义传递给函数的参数的顺序,而是由编译器使用的调用约定决定的。我认为在您的情况下,cdecl调用约定(许多 C 编译器用于 x86 架构)用于从右到左评估函数中的参数。

  • 这还应该提到代码具有*未定义的行为*。快速浏览此 Q/A 而不修改其他答案的人可能会忽略这一事实,并假设问题中的行为对于 cdecl 调用是可靠的。 (2认同)