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

发布于 2024-11-08 13:52:59 字数 443 浏览 3 评论 0原文

我也遇到过其他类似的问题,但试图了解我面临的情况。

所以,这是我的两行 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 是古老的编译器,现在已经过时且非标准,但仍然不知道上面的代码有什么问题。

I've gone through other similar questions, but trying to understand the situation I'm facing.

So, here's my two line C code.

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

And here are the outputs I get from GCC and Turbo C Compiler.

GCC

Output:

-1 0 0 0 0

Turbo C

Output:

-1 0 0 -1 0

I tried all sorts of experiments with pre-increment operator individually, and both compilers work similar but when I use above printf statement, output differs.

I know that Turbo C is age-old compiler and now obsolete and non-standard but still can't get an idea what's wrong with above code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

み青杉依旧 2024-11-15 13:53:00

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

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

通过在本网站搜索 [C] 未定义行为。这很有启发性。

It's undefined behavior, you're both reading and modifying i multiple times without a sequence point. (The , in the function parameter list is not a sequence point, and the order of evaluation of function arguments is not defined either.)

The compiler can output whatever it wants in this situation. Don't do that.

Find a whole host of other similar issues by search this site for [C] undefined behavior. It's quite enlightening.

执妄 2024-11-15 13:53:00

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

Turbo C is evaluating the arguments for printf() from the last argument in the variable arguments list to the first, and printing in that order as well (i.e., it's filling in the last value, and then moving forward in the list with the last evaluation being the first variable argument in the list, which prints to the first integer-slot in your formatted-string). GCC on the other-hand is first is evaluating the arguments that have pre-fix operators, concatenating those results, and applying them to all pre-fix operators (i.e., it's applying --i and ++i which ends up equaling 0, and then using that value for both slots in the format string associated with those arguments). It's then moving to the post-fix operators (first i-- and then i++) , and finally it evaluates the variable args with no pre-fix or post-fix operators (i.e., the value of i, which at this point is simply 0). As others have noted, the ordering can be arbitrary.

浅忆 2024-11-15 13:53:00

无法保证函数参数的求值顺序;这是未定义的行为。

此顺序可能会因版本而异,甚至可能会因编译而异。

There is no guarantee of the order in which function parameters are evaluated; it's undefined behaviour.

This order could change from version to version or even compile to compile.

北渚 2024-11-15 13:53:00

对于这种情况,在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 编译器对此类表达式的通常行为,而任何其他编译器对此类表达式没有具体规则。

There is a concrete explanation in case of Turbo C compiler for this case.

While GCC or other modern day compilers have an undefined behavior for such expressions where such ambiguity persists.

So, here's the explanation in the case of Turbo C compiler.

printf() has a right to left associativity while evaluating, but will print in its normal fashion of left to right.

Initially the value of i is initialized to 0,

starting with the rightmost i, it will be replaced by 0.

then, the second last --i, will be replaced by 0-1 = -1.

then the middle one ++i, will be replaced by -1+1 = 0.

then the second one i--, will be replaced by 0 but now the value of i becomes -1.

then the first one i++, will be replaced by -1 but now the value of i becomes 0.

And finally print in the left to right fashion as:

-1 0 0 -1 0

So, you can observe the usual behavior of Turbo C compiler on such expressions while there is no concrete rule of any other compiler on such expressions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文