I am using the following code in different compiler:
#include <stdio.h> int main(void) { int i = 0; int b[10] = {100,101,102,103,104,105,106,107,108,109}; int c[10] = {0,1,2,3,4,5,6,7,8,9}; b[i + 0] = c[i++ % 100]; b[i + 0] = c[i++ % 100]; b[i + 0] = c[i++ % 100]; b[i + 0] = c[i++ % 100]; b[i + 0] = c[i++ % 100]; b[i + 0] = c[i++ % 100]; for(i = 0; i < 10; i++) printf("b[%d] = %d\n",i,b[i]); return 0; }
But I am getting different output by using Keil, the output as follows:
//Keils output... uVision3 V3.53, compiler Armcc.exe b[0] = 100 b[1] = 0 b[2] = 1 b[3] = 2 b[4] = 3 b[5] = 4 b[6] = 5 b[7] = 107 b[8] = 108 b[9] = 109 //Microsoft Visual STD 6.0 output b[0] = 0 b[1] = 1 b[2] = 2 b[3] = 3 b[4] = 4 b[5] = 5 b[6] = 106 b[7] = 107 b[8] = 108 b[9] = 109 Press any key to continue //Microsoft Visual STD 2005 output b[0] = 0 b[1] = 1 b[2] = 2 b[3] = 3 b[4] = 4 b[5] = 5 b[6] = 106 b[7] = 107 b[8] = 108 b[9] = 109 Press any key to continue //Borland C++Builder6.0 output.... b[0] = 0 b[1] = 1 b[2] = 2 b[3] = 3 b[4] = 4 b[5] = 5 b[6] = 106 b[7] = 107 b[8] = 108 b[9] = 109
Could you tell me something about this problem?
Even when/if standards do specify exact order of evaluation, a developer should make sure that a reasonably skilled reader will understand the code.
It is easy to understand precedence rules for + in relation to *, but when expressions gets complex, extra parentheses should be added.
And expressions with side effects should really not be accepted, if the evaluation order and side effect may interfere. Just do not - ever - write code where you use ++ or -- on a variable and use the variable somewhere else in the same statement.
And do not write code where the address of the same variable is taken twice as parameters to a function call. The function will probably expect that there are no aliasing between the two pointers.
And do not try to write code that accesses a global variable both directly and through a pointer.
Thank you for your important advices.
Having said that, it does seem the Keil is a little bit out on it's own here. I just tried GCC and it works the same as the others.
Does add a rather tricky portability issue.
Actually it doesn't. The issue here is not portability but outright incorrecness of the code. Code along the lines of
a[i]=i++;
doesn't just yield an implementation-defined result, like some earlier respondents stated. It causes undefined behaviour --- which means no matter how unspeakably bizarre this code behaves, that's precisely correct.
You guys are ultimately discussing the wrong question here. You should worry about repairing the code, not about what compilers might make of it in its current, buggy state. It makes no sense whatsoever to discuss particular results of running this code on any compiler. It's impossible for any compiler to get this wrong.
It causes undefined behaviour --- which means no matter how unspeakably bizarre this code behaves, that's precisely correct.
My copy of K&R seems to disagree with that. It states that the order in which the operands of an operator (in this case: the assignment operator =) are evaluated is left to the compiler.
And in this case, the compiler has only two options - evaluate the left-hand operand first, or evaluate the right-hand argument first. Any behavior that's more bizarre than that would point to a faulty compiler. The compiler may not produce code that omits the statement, enters an endless loop, or exits the program, for example.
Of course, an evil-yet-standard-compliant compiler could flip a coin to determine the order of evaluation for every multi-operand operator it encounters. At least I didn't see anything about always having to chose the same order.
...
That doesn't constitute a disagreement. The problem is that 'i' is being modified more than once between sequence points which invokes undefined behaviour. Once that has happened all bets are off.
Every aspect of that paragraph is completely wrong. I suggest that you take a look at the comp.lang.c faq for 'undefined behaviour' and 'order of eveluation'.
I suggest that you take a look at the comp.lang.c faq for 'undefined behaviour' and 'order of eveluation'.
Interesting. The FAQ even mentions the discrepance between K&R (whose wording suggests that the behavior is unspecified) and the C standard (which states that the behavior is indeed undefined).
Advice taken, I'll make an appropriate note in my K&R.
"The problem is that 'i' is being modified more than once between sequence points which invokes undefined behaviour."
Note that a variable doesn't need to be modified multiple times between sequence points. In this case the user modified the value once, but combined the modification with a second use of the variable.
Yes, that's what I should have said...