gcc optimization in pre-increment & post-increment [duplicate] - c

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
I want to know on what criterias,gcc compiler decides to optimize the values of variables.?
Here is sample
int a=2;
printf("%d %d\n",a++,++a);
It gives output
3 4
Why does gcc optimizes and gives latest value of ain pre-increment and not in post increment?On which basis it takes decision?

It's undefined behavior. There is no specified order in which arguments are evaluated.

The code has two problems.
You change the value of a twice in the same expression, with no so-called "sequence point" between them. This is undefined behavior and anything can happen. See the FAQ for more information.
You have side effects in the parameters passed to a function, the side effect being a ++ increment. The order of evaluation of function parameters is unspecified behavior, meaning that the compiler has implemented it in some way, but we can't know how. It may be different from function to function, and certainly different from compiler to compiler.
One should never write code that relies on undefined or unspecified behavior. Even more info in the FAQ.

Related

The result of (a=a+1)+(a=a+1)+(a=a+1) in c? [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 6 years ago.
When I compile this code with gcc and run
int a=1;
printf("%d",(a=a+1)+(a=a+1)+(a=a+1));
I expect the result to be 2+3+4=9, but the output is 10.
I know that there is undefined behavior in (++a)+(++a)+(++a) , because the three ++ side effect can be run before all (++a) is evaluated.
But I think the value of a=a+1 is exactly what a is after the assignment is evaluated. So the compiler cannot process three a=a+1 first and use the value in variable a as the value of a=a+1 after all a=a+1 evaluated.
I want to know where is wrong according to the c standard.
The assignment operator is not a sequence point. Assuming a is just an identifier (e.g. not a macro argument that might expand to something more complicated) and does not have an atomic type (C11), a=a+1 is identical in semantics to ++a.
I wanted to mark this question as a duplicate of one of the hundreds of ++ operator sequence-point questions, but it seems your question is about why this form isn't different.

Execution of parameters in printf() function in C programming language [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 7 years ago.
While solving some aptitude questions on C programming language and I encountered a problem in which I have to tell the output. The program is :-
#include<stdio.h>
int main()
{
int x = 5;
printf("%d %d %d", ++x, x++, ++x);
return 0;
}
Now from my previous knowledge I know that the parameters of a printf() function are evaluated right to left. So solving this manually I'm getting output as :- 8 6 6
But the when I compiled this program I got the output as :- 8 6 8
Okay here is the question that seems bit related to this question but, there I'm specifically asking for the execution of parameters in the function not for the assignment operators.
Or does the execution of parameters happens randomly? If so, then some time it should give some different output but it is not giving. Even on different compilers it is giving the same output as 8 6 8.
why this anomaly?
Thanks
The order of evaluation in printf() is not left to right as you assumed. The evaluation order is unspecified:
From C11 draft (Annex J, unspecified behaviours)
The order in which the function designator, arguments, and
subexpressions within the arguments are evaluated in a function call
(6.5.2.2).
From, 3.4.4, unspecified behavior
Use of an unspecified value, or other behavior where this
International Standard provides two or more possibilities and imposes
no further requirements on which is chosen in any instance.
EXAMPLE An example of unspecified behavior is the order in which the
arguments to a function are evaluated.
So the three x++ expressions can be evaluated in any order. But this leads to undefined behaviour as you are attempting to modify the same object more than once without an intervening sequence point. The comma in a function designator is a separator, not the comma operator.
Because comma operator does introduce a sequence point between its operands.
The behavior is definitely unexpected, You are not supposed to change the value of a variable more than once in a function call. Rules of sequence points. Try looking at this link. And also read about sequence points in a program
Just try not changing the value of one variable more than once in a function call
There are two things interfering here:
the order of evaluation of function arguments is undefined (causing undefined results) -> the order can be anything because there is no order imposed by The Standard (The standard says: the order is unspecified)
there are no sequence points between the evaluations of the function arguments. (the function calling per se, and its return are sequence points, but that's irrelevant here)
What this means in practice: because the evaluating of the function arguments has side effects (the increments) there are multiple attempts to alter x's value without an intervening sequence point, causing Undefined Behaviour.

How does incrementation takes place in printf statement in C [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I printed the above line. But I got the result as 65.How does I increment and print despite the fact that I is incremented at the second time??
int i=5;
printf("%d%d",i,i++);
Your printf call produces undefined behavior. It is illegal to modify i (in i++) and at the same time perform an independent read of i without an intervening sequence point.
Various "orders of evaluation" do not matter here. All attempts to explain the behavior of this code based on the "orders of evaluation" or what happens "before" and what happens "after" are absolutely incorrect. The behavior is simply undefined. End of story.
As far as the C language itself is concerned, this code can print "Kill all humans!", crash the program, format your hard drive or simply refuse to compile.
The ANSI C99 ISO/IEC 9899:1999 standard says
6.5.2.2 Function calls
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual
arguments is unspecified, but there is a sequence point before the
actual call.
as you just discovered, the order of evaluation is unspecified. The compiler is free to evaluate the arguments in any order. (In your case, i++ is evaluated before i.)

Explain the order of evaluation in printf [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 4 years ago.
main()
{
int i=5;
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
}
Output is 45545, but I don't how it is working. Some say that the arguments in a function call are pushed into the stack from left to right.
The evaluation order of function parameters is unspecified.
From c99 standard:
6.5.2.2 Function calls
10/ The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is
unspecified, but there is a sequence point before the actual call.
This is, however, only a part of the problem. Another thing (which is actually worse, since it involves undefined behavior) is:
6.5 Expressions
2/ Between the previous and next sequence point an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be read only to
determine the value to be stored.
In our case all the arguments evaluation is between only 2 sequence points: the previous ; and the point before the function is entered but after all the arguments have been evaluated. You'd better not write a code like this.
C standard is pretty relaxed in some places to leave room for optimizations that compilers might do.
The order in which the parameters to a function are passed is not defined in the standard, and is determined by the calling convention used by the compiler.
I think in your case, cdecl calling convention (which many C compilers use for x86 architecture) is used in which arguments in a function get evaluated from right to left.
This function call is undefined behavior:
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
Modifying an object more than once between two sequence points is undefined behavior in C.
It is also undefined behavior because you have 6 conversion specifications but only 5 arguments for the format.
Two points:
Function arguments are evaluated in an unspecified order. This allows the compiler to optimize however it likes.
Your particular arguments invoke undefined behavior. You're not allowed to modify i multiple times before a sequence point.
The evaluation order of printf arguments is unspecified. It depends, among other, on the calling convention of the system you are using. Moreover, this is also an undefined behavior, because you are modifying i several times without any sequence point. BTW, there is a missing argument.

Ambiguity in answer in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
I have heard that printf function executes from right to left and prints from left to right. By that convention, the following program should give 7,6,5. But it's giving 7,7,7 on my linux gcc compiler. Is it compiler dependent?
int i=5;
printf("%d %d %d\n",++i,++i,i);
Also, can we use cdecl/pascal keyword to change the order of execution of printf? If yes, how do we do that? I have been trying to do this but without success. Thanx in advance!
The evaluation order in your code is undefined, as there are no sequence points. You cannot relay on the evaluation order of function arguments, and you cannot change it either.
Check http://www2.research.att.com/~bs/bs_faq2.html#evaluation-order
There is no order dictated by the standard in function calls, so the arguments can be evaluated in any order the compiler seems fit. So if you have side effects in the evaluation of the parameters, you get undefined behavior.

Resources