The code below displays different results when compiled and run on Code::Blocks.
void sum(int a,int b){
printf("a=%d b=%d\n",a,b);
}
int main(){
int i=1;
sum(i=5,++i);
printf("i=%d\n\n",i);
/***********************/
i=2;
sum(i=5,i++);
printf("i=%d\n\n",i);
/**********************/
i=3;
sum(i=5,i);
printf("i=%d\n\n",i);
return 0;
}
Output:
a=5 b=5
i=5
a=5 b=2
i=5
a=5 b=5
i=5
I think the answer to this question is related to sequence point and the sequence point is related to ++ operator here. GCC must be following an order to pass the value to stack in a fixed order but because of ++ the answers are different. I think for a beginner to write a function call like this is not very common, but the lesson about operators are general so one can try.
My questions are,what should be the exact answer of it and questions like it? During which phase of compilation these things are decided(made it clear or unclear)? Which particular algorithm(s) (either for optimization or in general) is involved? Can same compiler provide different result for such expression or statements? And the last on is, how a beginner will understand and figure out these problems? It is sometimes very surprising.
The order of operations is decided during multiple phases of compilation, which is what causes the odd results you see. During the optimization phase in particular the compiler can reorder code in ways that aren't always obvious, and in this case it's affecting the result (which is fine, because you're doing something undefined and the compiler's explicitly allowed to do anything it wants to with that code). There isn't any specific algorithm involved, it's an interaction between several different algorithms applied at different points and the algorithm applied at each point can vary depending on what the compiler's decided is the best way to handle a particular bit of code.
When the documentation speaks of undefined behavior, it's not the behavior of a specific compiler that's undefined but the specification of what the compiler must or is allowed to do. The compiler's behavior is completely defined, but it's defined by detailed decisions buried deep in the design of it's parser, code generator and optimizer modules and it's complicated enough that not even the developers who wrote the compiler can tell you what it'll do without spending a lot of time analyzing how a given bit of code flows through the entire process.
A beginner won't be able to figure out the outcome. Even an expert developer may not be able to. That's why "undefined" is such an unwelcome word to developers, and why they try to avoid undefined behavior like the plague. To quote from a discussion of the language spec in question, "In short, you can't use sizeof() on a structure whose elements haven't been defined, and if you do, demons may fly out of your nose.".