C编译器GCC和Turbo的奇怪行为

时间:2011-05-20 05:11:24

标签: c gcc turbo-c

我已经经历了其他类似的问题,但试图了解我所面临的情况。

所以,这是我的两行C代码。

int i=0;
printf("%d %d %d %d %d",i++,i--,++i,--i,i);

以下是我从GCC和Turbo C编译器获得的输出。

GCC

输出:

-1 0 0 0 0

Turbo C

输出:

-1 0 0 -1 0

我尝试了单独使用预增量运算符的各种实验,并且两个编译器的工作方式类似,但是当我使用上面的printf语句时,输出会有所不同。

我知道Turbo C是一个古老的编译器,现在已经过时和非标准,但仍无法知道上面的代码有什么问题。

4 个答案:

答案 0 :(得分:8)

这是未定义的行为,您在没有序列点的情况下多次读取和修改i。 (函数参数列表中的,不是序列点,也没有定义函数参数的评估顺序。)

编译器可以在这种情况下输出任何想要的内容。不要那样做。

通过在[C] undefined behavior搜索此网站,查找大量其他类似问题。这很有启发性。

答案 1 :(得分:1)

Turbo C正在将printf()的参数从变量参数列表中的最后一个参数计算到第一个参数,并按此顺序打印(即,它填充最后一个值,然后继续前进最后一次评估的列表是列表中的第一个变量参数,它打印到格式化字符串中的第一个整数槽。另一方面,GCC首先评估具有预先修复运算符的参数,连接这些结果,并将它们应用于所有预修复运算符(即,它应用--i++i结束up等于0,然后将该值用于与这些参数关联的格式字符串中的两个槽。然后它转移到后修复操作符(第一个i--然后是i++),最后它评估变量args而没有预先修复或后修复操作符(即{{{ 1}},此时只是i)。正如其他人所指出的那样,排序可以是任意的。

答案 2 :(得分:0)

无法保证评估功能参数的顺序;这是未定义的行为。

此订单可能会从版本更改为版本,甚至可以编译为编译。

答案 3 :(得分:0)

对于这种情况, Turbo C 编译器有一个具体的解释。

虽然 GCC 或其他现代编辑器对此类歧义持续存在未定义行为

所以,这是 Turbo C 编译器的解释。

printf()在评估时具有从右到左的关联性,但会以从左到右的正常方式打印。

最初 i 的值初始化为 0

从最右边的 i 开始,它将被 0 取代。

然后,第二个 - i 将替换为0-1 = -1

然后中间的一个 ++ i ,将被-1 + 1 = 0 取代。

然后第二个 i - ,将被 0 取代,但现在i的值变为-1。

然后第一个 i ++ ,将被 -1 取代,但现在i的值变为0.

最后以左到右的方式打印:

-1 0 0 -1 0

因此,您可以观察 Turbo C 编译器对此类表达式的通常行为,而此类表达式上没有任何其他编译器的具体规则。