在printf中解释评估顺序
可能重复:
C函数调用之前的参数评估顺序
main() { int i=5; printf("%d%d%d%d%d%d",i++,i--,++i,--i,i); }
输出是45545,但我不知道它是如何工作的。 有人说函数调用中的参数是从左到右推入堆栈的。
函数parameter passing的顺序没有在标准中定义,而是由编译器使用的调用约定决定的。 我认为在你的情况下,使用cdecl调用约定(许多C编译器用于x86架构),函数中的参数从右向左评估。
function参数的评估顺序是未指定的。
从c99标准:
6.5.2.2函数调用
10 /实际参数中函数指示符的评估顺序,实际参数和子expression式是未指定的,但在实际调用之前有一个顺序点。
但是,这只是问题的一部分。 另一件事(实际上更糟,因为它涉及未定义的行为)是:
6.5expression式
2 /在前一个和下一个序列点之间,一个对象应该通过评估一个expression式来最多修改一次对象的存储值。 此外,先前的值应该是只读的,以确定要存储的值。
在我们的例子中,所有的参数评估只在两个序列点之间:前一个;
和input函数之前的点,但所有的参数已被评估。 你最好不要写这样的代码。
C标准在一些地方相当放松,为编译器可能做的优化留下空间。
printf
参数的评估顺序是未指定的。 这取决于您正在使用的系统的调用惯例。 此外,这也是一个未定义的行为,因为你正在修改i
几次没有任何顺序点。 顺便说一句,有一个失踪的论点。
这个函数调用是未定义的行为:
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
在两个序列点之间多次修改一个对象在C中是未定义的行为
这也是未定义的行为,因为你有6个转换规范,但格式只有5个参数。
两点:
- 函数参数以未定义的顺序进行评估。 这使编译器可以优化,但它喜欢。
- 您的特定参数调用未定义的行为。 在序列点之前,您不允许多次修改
i
。