How does it works? Sequence of computing variable into printf [duplicate] - c

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.

Related

I'm not able to figure out how this code produces this output [duplicate]

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

C - Output explanation of printf("%d %d\n",k=1,k=3); [duplicate]

This question already has answers here:
Explain the order of evaluation in printf [duplicate]
(5 answers)
Closed 6 years ago.
How to explain the output of the below code:
include <stdio.h>
int main(void) {
int k;
printf("%d %d\n",k=1,k=3);
return 0;
}
Ideone Link
My thinking was that 1 will be assigned to k variable and then 1 would be printed. Similarly 3 will be assigned to k and output will be 3.
Expected Output
1 3
Actual Output
1 1
I am extrapolating from
int a;
if (a = 3) {
...
}
is equal to
if (3) {
...
}
Please let me know where am I going wrong?
The problem is, the order of evaluation of function arguments are not defined, and there's no sequence point between the evaluation or arguments. So, this statement
printf("%d %d\n",k=1,k=3)
invokes undefined behavior, as you're trying to modify the same variable more than once without a sequence point in between.
Once a program invoking UB is run and (if) there's an output, it cannot be justified anyway, the output can be anything.
I expect the reason you're seeing 1 1 is because the two assignment statements are happening control is passed to printf.
printf("%d %d\n",k=1,k=3);
So in response to the down-votes, yes, this this is undefined behavior, and therefore you shouldn't count on this behavior continuing. However, in terms of identifying why the output was 1 1 and not 1 3, we could infer that the assignment of 3 may have been stomped on by a subsequent assignment of 1.
When printf is invoked, the call stack contains two entries containing the final value of k, which is 1.
You can test this out by replacing those with a function that prints something when it executes.
Sample Code:
#include <stdio.h>
int test(int n) {
printf("Test(%d)\n", n);
return n;
}
int main(void) {
int k;
printf("%d %d\n",k=test(1), k=test(3));
return 0;
}
Output:
Test(3)
Test(1)
1 1

Define in C does not work when input is composite [duplicate]

This question already has answers here:
What is argument evaluation?
(2 answers)
Closed 6 years ago.
Problems using define in C. Works well when I call OP(9), but when I call OP(7+2) I get 23. Why?
#include<stdio.h>
#include<stdlib.h>
#define OP(x) x*x;
int main() {
int x,y;
x = 2;
y = OP(7+2);
printf("%d", y);
return 0;
}
Why prints 23 and not 81?
You should wrap x in parentheses in order to force precedence. However, it is also essential to wrap the entire expression in parentheses.
#define OP(x) ((x)*(x))

gcc compiler printf execution order [duplicate]

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.

Evaluation order of increment operations 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 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.

Resources