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?
There is no problem. The behavior of statements like
a[i] = i++:
is implementation-defined in C (see K&R, chapter "Precedence and Order of Evaluation". It contains this example). Different compilers are free to evaluate the left or the right side of the assignment first.
It is up to the programmer to deal with the consequences.
Thank you for your reply.
In visual STD the following code:
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; }
generates the following output(there is no difference):
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
And the following code:
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; }
Generates the following output:
b[0] = 0 b[1] = 101 b[2] = 2 b[3] = 3 b[4] = 4 b[5] = 5 b[6] = 6 b[7] = 107 b[8] = 108 b[9] = 109
With a visual studio background, I think or hope that would be the same in keil.
No - you need a standard C background, and this would tell you that you cannot expect any particular order in which the left and the right side of a statement are evaluated. This also means that side effects of the statements may occur in either order. If you require a certain order even across different compilers, you will need to change the code accordingly.
Compilers don't work to arbitrary user's thoughts and hopes - they work to their published specifications, which will be based on appropriate standards.
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.
View all questions in Keil forum