问题
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.
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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.
来源:https://stackoverflow.com/questions/6067722/a-weird-behavior-of-c-compilers-gcc-and-turbo