This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
confused about printf() that contains prefix and postfix operators.
I came across a code with the following snippet,
int main() {
int c = 100;
printf("\n %d \t %d \n", c, c++);
return 0;
}
I expected the output to be 100 & 101 but I get output as
101 100
Could anyone help me know why?
The C and C++ standards do not guarantee the order of evaluation of function parameters. Most compilers will evaluate parameters from right to left because that is the order they get pushed on the stack using the cdecl calling convention.
There is no guarantee whether c on the left, or c++ on the right, will be evaluated first.
The order of evaluation of function parameters is Unspecifeid and hence Undefined Behavior as per the standard.
As per Section 1.9 of the C++ standard:
"Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, order of evaluation of arguments to a function). Where possible, this International Standard defines a set of allowable behaviors. These define the nondeterministic aspects of the abstract machine."
If you had just used printf ("%d\n", c++) or printf ("%d\n", c) the result would have been 100 in either case. Printing both c and c++ in one function call as you did is undefined behavior.
printf works from right to left so first c++ is executed (c= 100) then after C++ executes and C=101
therefore 101 and 100 is output
http://en.wikipedia.org/wiki/Printf
Related
This question already has answers here:
Is the output of printf ("%d %d", c++, c); also undefined?
(6 answers)
Closed 6 years ago.
I am unable to understand the below issues while pre-incrementing and post-incrementing a variable inside printf:-
code used in turbocpp compiler:-
#include<stdio.h>
main()
{
int i=0;
clrscr();
printf("%d %d %d",i,i++,++i);
getch();
return(0);
}
the output in MSdos Compiler is :- 2 1 1
but for the same program in DevC++ 5.11 the output is:- 2 1 2
1) My understanding is printf prints by taking left variable first and then moves to right.(i have verified it using 3 different variables.) So, according to that shouldn't the output be 0 0 2?
2) I tried with DevC++ to check the output of the same program but it gave a different result. Now I am really confused as what should be the output.
3) Also if I vary:- printf ("%d %d %d", i,++i,i++); the output is 2 2 0.
I am not getting what is going on here. Somebody Please help me to understand better...
Having two side effects on the same variable will give you an undetermined result, as each compiler is free to choose the order in which it evaluates the arguments.
1.9/15: If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a
value computation using the value of the same scalar object, the
behavior is undefined.
So it could for example be:
0,0,1 if evaluated left to right
2,1,1 if evaluated right to left
2,1,2 if pre-increment is done on i and stored in i, then i is loaded as second argument and post incremented, then i is taken ans third argument (the compiler assuming that preincrement was already done), and then i is taken as first argument.
But other combinations could also be plausible. And undefined behaviour means really undefined, so perhaps one day this could even crash (if one say a compiler would automatically generate parallel code and 2 cores access to the same variable in the same time)
C++ doesn't standardize the order in which function arguments are calculated, that's why results differ from compiler to compiler. See C++ Standard, section 5.2.2/8:
The order of evaluation of arguments is unspecified.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
How the statement x=x++ + y++; executes to the value 3?
I was wondering how printf work in a case like this:
int i = 0;
printf("%4d%4d", i++, i);
Result is 0 1
in another case
int i = 0;
printf("%4d%4d", i, i++);
Result is 1 0
This has nothing to do with printf, and everything to do with the order in which the parameters are evaluated and the way the compiler executes your code. The behavior is undefined, and the results will depend on your compiler, calling convention, and phase of the moon.
In both your examples, the rules of pre/post incrementing are taking precedence. Your particular compiler understands that it must use the value of i before evaluating the increment, and is giving precedence to the parameter that invokes a function call over the one that doesn't. Your second usage of the variable i is causing the compiler to insert an intermediary statement in the process of calling printf,
It's important to note that i++ doesn't mean (as is commonly taught) "increment i after executing this line", it just means "increment i at some point after giving me its value, and before executing the next line". That's a lot of wiggle room for the compiler to do what is formally called "undefined behavior."
As #Als points out in a comment, you've managed to combine both undefined and unspecified behaviors in one line of code.
This is not due to printf it's due to you being in a case of undefined behaviour
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
FAQ : Undefined Behavior and Sequence Points
Different outputs on different compiler?
Is this true that certain statements can generate different outputs on different compilers. I have two compilers handy gcc and msvc expression edition. When I tried a code sample on both of them I was shocked to see different outputs on them.
This was the code sample.
#include<stdio.h>
int main(void)
{
int variable_a = 100;
printf("%d %d", ++variable_a, variable_a++); return 0;
}
Output that I got on gcc was 102 100
On msvc I got 102 101.
Why such a difference?
You invoke undefined behaviour by incrementing a more than once. Any compiler would be within their rights to break into your house and beat you with a stick.
There are various subtle effects of this kind where the language is explicitly undefined. There's a lot of history behind why the language leaves these corners undefined. From the coder's point of view we need to avoid certain patterns such as the one you stumbled across.
See this reference for some explanation
What should be the output of the following code and why? I am little bit confused.
int a =10;
printf("%d %d %d",a,a=a+10,a);
The output is indeterminate, because a=a+10 is a side-effect, and the compiler is free to evaluate it before or after any of the other parameters.
EDIT: As David points out, the behaviour is actually undefined, which means all bets are off and you should never write such code. In practice, the compiler will almost always do something plausible and unpredictable, maybe even differing between debug and optimised builds. I don't think a sperm whale is a likely outcome. Petunias? Perhaps.
The order of evaluation for a, b, and c in a function call f(a,b,c) is unspecified.
Read about sequence points to get a better idea: (The undefined behavior in this particular case is not due to sequence points. Thanks to #stusmith for pointing that out)
A sequence point in imperative programming defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed. They are often mentioned in reference to C and C++, because the result of some expressions can depend on the order of evaluation of their subexpressions. Adding one or more sequence points is one method of ensuring a consistent result, because this restricts the possible orders of evaluation.
Sequence points also come into play when the same variable is modified more than once. An often-cited example is the expression i=i++, which both assigns i to itself and increments i; what is the final value of i? Language definitions might specify one of the possible behaviors or simply say the behavior is undefined. In C and C++, evaluating such an expression yields undefined behavior.
Thanks for the answers.... :)
The behavior is really undefined and compiler dependent. Here are some outputs
Compiled with Turbo c :
20 20 10
Compiled with Visual Studio c++:
20 20 20
Compiled with CC:
20 20 20
Compiled with gcc:
20 20 20
Compiled with dev c++:
20 20 10
Not defined.
The evaluation order of a function parameters is not defined by the standard.
So the output of this could be anything.
using Mingw Compiler in Bloodshed Dev C++ : 20 20 10
Not to amend previous correct answers, but a little additional information: according to the Standard, even this would be undefined:
int a =10;
printf("%d %d %d", a = 20, a = 20, a = 20);
It is highly compiler dependent.
Because evaluation order of arguments is not specified by standard.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 25 days ago.
x = 1;
std::cout << ((++x)+(++x)+(++x));
I expect the output to be 11, but it's actually 12. Why?
We explain it by expecting undefined behaviour rather than any particular result. As the expression attempts to modify x multiple times without an intervening sequence point its behaviour is undefined.
As others have said, the C and C++ standards do not define the behaviour that this will produce.
But for those people who don't see why the standards would do such a thing, let's go through a "real world" example:
1 * 2 + 3 + 4 * 5
There's nothing wrong with calculating 1 * 2 + 3 before we calculate 4*5. Just because multiplication has a higher precedence than addition doesn't mean we need to perform all multiplication in the expression before doing any addition. In fact there are many different orders you validly could perform your calculations.
Where evaluations have side effects, different evaluation orders can affect the result. If the standard does not define the behaviour, do not rely on it.
This is actually undefined. C++ doesn't define explicitly the order of execution of a statement so it depends on the compiler and this syntax shouldn't be used.
The code snippet will invoke Undefined behavior in both C/C++.Read about Sequence Point from here.
In my opinion
cout<<((++x)+(++x)+(++x));
compiler first run prefix ++x so value of x becomes
x=2
now by ++x, x will become
x=3
after ++x
x=4
Now its time to add values of x
x+x+x=4+4+4
x+x+x=12