This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I executed following following code.
int main(void)
{
int c;
c=0;
printf("%d..%d..%d \n", c,c,c);
c=0;
printf("%d..%d..%d \n", c,c,c++);
c=0;
printf("%d..%d..%d \n", c,c++,c);
c=0;
printf("%d..%d..%d \n", c++,c,c);
return 0;}
I expected the output as
0..0..0
1..1..0
0..1..0
0..0..0
But the output(compiled with gcc) was
0..0..0
1..1..0
1..0..1
0..1..1
What is wrong with my expectation?
In gcc ,evaluation order is from right to left. Is It?
What is wrong with my expectation?
Evaluation order of function parameters is not specified - it is left up to the implementation. Moreover, there is no sequence point * between the parameters, so using a modified parameter again before a sequence point cannot give you a predictable result: it is undefined behavior (thanks, Eric, for providing a reference to the standard).
If you want a particular evaluation order, you need to evaluate your parameters as full expressions (that forces a sequence point between each of them):
int arg1 = c++;
int arg2 = c;
int arg3 = c;
// This: printf("%d..%d..%d \n", c++,c,c);
// Becomes this:
printf("%d..%d..%d \n", arg1, arg2, arg3);
* Sequence point is a fancy name for a place in code after which you can count on side effects, such as increments or decrements, of all preceding expressions to have been applied.
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 1 year ago.
I'm not able to understand, why this code produces this output. Can anyone help me with this??
#include <stdio.h>
int main( void )
{
int num = 5;
printf( "%d %d %d", num, ++num, num++ );
}
The output will be 7 7 5 (and NOT 5 6 7)
Making side effects happen in the same order as in some other compiler.
It is never safe to depend on the order of evaluation of side effects. For example, a function call like this may very well behave differently from one compiler to another:
void func (int, int);
int i = 2;
func (i++, i++);
There is no guarantee (in either the C or the C++ standard language definitions) that the increments will be evaluated in any particular order. Either increment might happen first. func might get the arguments ‘2, 3’, or it might get ‘3, 2’, or even ‘2, 2’.
https://gcc.gnu.org/onlinedocs/gcc/Non-bugs.html
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 2 years ago.
stumbled upon such a puzzle:
What will be shown on the screen?
#include <stdio.h>
void main()
{
int x = 10;
printf("x = %d, y = %d", x--, x++);
}
Curiously enough, but shown at the screen this: x = 11, y = 10;
But how??
Argument Evaluation Order is undefined in both C and C++. It's important to avoid any code that passes expressions dependent on each other that has to be evaluated before the function is called. It's a strict no.
int f1() { printf("F1") ; return 1;}
int f2() { printf("F2" ) ; return 1;}
printf("%d%d", f1(), f2()) ;
You can check out by adding several functions that contain a print statement and pass it to a function to observe this in action. You don't know what's coming, the C standard doesn't specify it, it depends on what compiler you use and how it optimizes your code.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
#include<stdio.h>
int main() {
int x = 99;
printf("%d %d\n",1 > scanf("%d",&x) ? scanf("%d",&x): scanf("%d",&x),x);
}
So What is happening to the scanned values.
Lets say First Input is 11. so left most scanf is returning 1. So according to the rule the right most scanf will be executed. But The right most %d of printf is not printing the scanned value. It is showing 99.
You have unidefined behavior.
That is because you are modifying a value and accessing that value without an intervening sequence point. A simplified example with the same problem:
int x, y;
x = 1;
y = scanf("%d", &x) + x; /* <--- UB! */
Or also:
int x = 1;
printf("%d %d", x = 11, x); /* <--- UB! */
Note that while the ?: does insert a sequence point just after the condition, the comma that separates arguments in a function call does not. This measn, not only that the order of evaluation of function arguments is unspecified, but also that you must not modify the same value twice in the arguments of a function, or modify and use the same argument.
For example this other example is also UB:
int x = 0;
printf("%d %d", x++, x); /* <--- UB! */
Or this one:
int x[10] = {0}, i = 0;
printf("%d %d", x[i++], x[i++]); /* <--- UB! */
The solution for your problem is to separate the code in nice orderly sentences. A full sentence always ends with a sequence point!
int x = 99;
int y = 1 > scanf("%d",&x) ? scanf("%d",&x): scanf("%d",&x); /* ARGH! */
printf("%d %d\n", y, x);
Now, the line marked with the exclamation is quite nonsensical, but at least it is UB-free.
Function arguments may be evaluated in any order. In this case, it looks like x evaluates to 99 before scanf is called. The order of function argument evaluation is unspecified in C. This is C FAQ #3.7:
The comma operator does guarantee left-to-right evaluation, but the commas separating the arguments in a function call are not comma operators. [...] The order of evaluation of the arguments to a function call is unspecified.
Because there is no sequence point between the scanf that modifies x and the function argument that evaluates it, you are invoking undefined behavior, as explained in rodrigo's answer.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
For the testing code as follow:
#include <stdio.h>
int addTen(int x, int b[])
{
b[2] = x + b[2];
return b[2];
}
void main(void)
{
int a[3] = {4,5,6};
int i = 2;
printf("%i %i %i \n", a[i], addTen(10,a), a[i]);
}
Why is the output is 16, 16, 6? I know that even if the compiler processes the order from right to left like a[i] <- addTen(10,a) <-a[i]. After calling addTen(10,a), a[i] is already 16 (not 6). So why the output is not 16, 16,16? THANKS!
It's undefined behavior, you should read about sequence points. You're modifying a and simultaneously reading it in a same expression.
In addition the order of evaluating is not defined.
There's no order defined for evaluating arguments. The compiler is free to evaluate arguments in any order, and will normally choose the most convenient order. So, you can't define any expected output.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Sequence points when calling functions in C and undefined/unspecified behaviour
(2 answers)
Closed 9 years ago.
I am decrementing an integer while passing it to a function. But am seeing some unexpected behavior. I'm new to C, and not sure what to make of it:
#include <stdio.h>
void func(int, int);
int main(){
int i=3;
//func(i--, i); //Prints a=3, b=2
func(i, i--); //Prints a=2, b=3 ??
func(i, --i); //Prints a=2, b=2 ??
}
void func(int a, int b){
printf("a=%d\n", a);
printf("b=%d\n", b);
}
The first call to func works as expected, but what is the deal with the second and third calls?
The order of calculation of function arguments is not specified. E.g. GCC likes to calculate the argument values from right to left. When you have an operator that modifies a variable (or have any other side effect), there must be a sequence point between that operator and any other expression that uses that variable.
This is undefined bahavior, you can't expect either result.
Since parameters passes in a function from right, so in first call where you used post increment operator- it passes the same value (3) and update the value for 'i' left parameter (2).
while in second call, you used pre increment operator which changes itself for right parameter and sends updated values for left parameter.