开发者

A weird behavior of C compilers GCC and Turbo [duplicate]

开发者 https://www.devze.com 2023-03-07 09:54 出处:网络
This question already has answers here: 开发者_如何学Go Why are these constructs using pre and post-increment undefined behavior?
This question already has answers here: 开发者_如何学Go Why are these constructs using pre and post-increment undefined behavior? (14 answers) Closed 8 years ago.

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.


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消