C(gcc)编译器中的增量和减量



有人能告诉我评估答案的正确程序吗(内部工作)?

#include<stdio.h>
main()
{
int a=10;
printf("%d %d %dn",a,a++,++a);
return 0;
}

此代码没有单一的、正确的行为
从技术上讲,该程序的任何输出或结果都是正确的,甚至是鼻恶魔

它属于未定义的行为

虽然我们可以猜测可能的的可能结果,但在这种情况下,C语言允许任何事情。

在表达式的单个1部分内,不允许(在C的定义行为内)两次修改对象或修改对象并分别使用其值。

表达式printf("%d %d %dn",a,a++,++a)包含aa++++a。这是不允许的,因为a++++a都修改了a。这也是不允许的,因为a使用a并且a++分别修改a

不要这样写代码

执行此操作时,行为是未定义的。编译器可能会以任何顺序评估这三件事,也可能会"中断"并执行完全不同的操作。你可能得到了"12 11 12",因为编译器生成的代码做到了这一点:

  • 首先,记录a++将具有的值(11),并计算递增的值(12),但将该值保存在临时寄存器中(还不要将其写入内存)
  • 其次,记录++a的值(12,因为a仍然是11)
  • 第三,更新a的值,从临时或从++a或两者都更新
  • 第四,记录a的值(现在是12)
  • 第五,将这些值12、11和12传递给printf

但代码可能做了其他事情。在这种情况下,您只能通过检查生成的程序集代码来判断。你无法从C标准中判断出什么,因为C标准没有说明在这种情况下会发生什么。检查汇编代码只会告诉你在这种情况下会发生什么;当为不同的处理器体系结构编译相同的C源代码时,当使用不同的编译开关时,或者当编译器版本更改时,它可能会有所不同。


1表达式可以按序列点划分为多个部分。有关序列点的更多信息,请参阅此答案。

最新更新