变量的前后增量运算在TC和gcc上给出不同的输出

时间:2011-12-30 16:52:16

标签: c gcc standards turbo-c

这是我的简单代码......

#include<stdio.h>
int main()
{
int i=5;
printf("%d %d %d %d %d ",i++,i--,++i,--i,i);
return 0;
}

在gcc上,它输出为“4 5 5 5 5”

但在TC上,输出为“4 5 5 4 5”

我知道在printf语句中,如果是单个表达式,则评估将从左到右,但在正常语句中,它将从左到右。

但是如果printf包含多个表达式,那么评估将在堆栈上,元素将从左到右推入堆栈但从右到左弹出并证明TC输出是正确的

请纠正我在哪里错了???

5 个答案:

答案 0 :(得分:8)

C没有指定应该评估哪些顺序函数参数,因此它是未定义的,编译器可以选择它,包括任意和随机。 Bjarne Stroustrup在“The C ++ Programming Language”第3版第6.2.2节中明确地说明了这一点

他也给出了一个理由:

Better code can be generated in the absence of restrictions on expression evaluation order

答案 1 :(得分:3)

我认为没有指定评估函数调用的参数的顺序。正如维基百科在关于序列点的this文章中所说:

  

未指定评估参数的顺序

答案 2 :(得分:3)

在前一个和下一个序列点之间多次修改一个对象(在此代码i中)是C中未定义的行为。这里的序列点出现在所有参数被评估之后的函数调用中。

答案 3 :(得分:0)

此时的两个答案会调用函数参数评估的 unspecifiedness 。正确答案是您的程序未定义,因为对sequence point未分隔的同一变量产生副作用。

实际上,函数参数的评估顺序是未指定。这意味着在f(g(), h());语句中,在g()之前调用h()或在之后调用它。

但是,未经测试的副作用(如在您的程序中)会调用未定义的行为,可能发生任何事情。

答案 4 :(得分:0)

提出一个旧主题,但我刚刚发现gcc和Visual Studio编译器如何处理语句中同一变量的多个更改,所以想在这里分享它。

这里定义的编译器开始对printf中传递的参数实现堆栈方法,即'i'。它遵循以下规则: -

1)现在它首先执行预增量,因此从右边正常开始然后--i然后执行++ i并且在++ i之后的i的值是5,所以它实现了这些值(pops)所以输出 _ _ 5 5 5

2)然后它从右到左继续并执行后增量因此,i--然后i ++因此i的值最终返回到5但由于i--它变为4但由于它显示5作为后增量,因此最终输出 4 5 5 5 5 ,i的最终值为5

希望我能清除你的怀疑。

TC不遵循这一点,因此它坚持我们的人类逻辑。