This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Sequence Points between printf function args; does the sequence point between conversions matter?
(3 answers)
Closed 3 years ago.
Consider code below:
#include <stdio.h>
int main()
{
int x=0,y=5;
printf("x=%d,x_1=%d,sum=%d",x++,x,y+x);
return 0;
}
My assumption on this code was that, x would be printed as 0 and later on postincrement x_1 would be 1 and y+x be 5+1=6
Actual result is x as 0 as expected , x_1 as 1 as expected. But y+x be 5. I am unsure why x retains its previous value though an postincrement had occured. Could you please help clarify this?
I used gcc compiler for the same.
In
printf("x=%d,x_1=%d,sum=%d", x++, x, y+x);
// (a) (b) (b)
you are both updating x (a) and using its value (b) in the same expression (with no intervening sequence point).
That's Undefined Behaviour.
Try
printf("x=%d,x_1=%d,sum=%d", x, x + 1, y + x + 1);
x++;
This is standard undefined behaviour, order of evalution of function arguments is non deterministic. Read [Why are these constructs using pre and post-increment undefined behavior?
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 2 years ago.
Can anybody tell me how the answer of this code is 16 25
#include<stdio.h>
#define sqr(x) ++x * ++x
int main()
{
int a = 3, z;
z = ++a * ++a;
a -= 3;
printf("%d %d", sqr(a), z);
return 0;
}
Compiling the code with -Wall option gives the following warning:
[Warning] operation on 'a' may be undefined [-Wsequence-point]
The results are platform and version dependent. Using such an expression results undefined behaviour. Therefore, such an expression must not be used.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I have idea about macro preprocessor directive.In below question how replacement in source code is done by compiler that it is giving output as
"y is 392"
#include <stdio.h>
#define CUBE(x) (x*x*x)
void main(void)
{
int x;
int y;
x = 5;
y = CUBE(++x);
printf("y is %d\n", y);
}
output:y is 392.
The behaviour of your code is undefined.
CUBE(++x) expands to (++x * ++x * ++x): there are no sequencing points in that expression and it simultaneously reads and writes to x.
This epitomises why macros that do arithmetic are computationally lethal.
The preprocessor is replacing that with
y = (++x*++x*++x);
Which is undefined behaviour.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
Kindly explain the output for the following code:
#include<stdio.h>
#include<stdlib.h>
#define SQUARE(x) (x*x*x)
int main() {
int x = 3;
int y = SQUARE(++x)/x++; // Undefined behavior even though it doesn't look
// like it here
printf("%d %d",x,y);
return 0;
}
Output: 7 25
Please explain how the value of y comes to be 25?
The macro is misnamed, but that's just a red herring. The two statements expand to:
int x = 3;
int y = (++x * ++x * ++x) / x++;
This is undefined behavior, since x is being modified more than once between sequence points. The compiler is allowed to do almost anything; it can interleave the uses of x and the pre- and post-increments of x almost anyway it wants. It can do things left-to-right, in which case, you get:
int y = (4 * 5 * 6) / 6;
Under this scheme, x is now 7 and y is now 20.
It could have done things right-to-left:
int y = (7 * 6 * 5) / 3;
Now, y is 70.
It could have cached the value of x at almost any point and used it. Try running your program under various compilers, with various optimization levels. Does gcc -O4 differ from cc? In fact, quoting the Internet Jargon file:
nasal demons: n.
Recognized shorthand on the Usenet group comp.std.c for any unexpected behavior of a C compiler on encountering an undefined construct. During a discussion on that group in early 1992, a regular remarked “When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose” (the implication is that the compiler may choose any arbitrarily bizarre way to interpret the code without violating the ANSI C standard). Someone else followed up with a reference to “nasal demons”, which quickly became established. The original post is web-accessible at http://groups.google.com/groups?hl=en&selm=10195%40ksr.com.
So, I'd be a lot more careful here. Do you want demons flying out of your nose?
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 10 years ago.
Cannot explain the output of the following program. According to my knowledge the output should be 19, but running it gives me output of 20. I used gcc to compile this program.
int main()
{
int x, y = 5;
x = ++y + ++y + --y;
printf("%d", x);
return 0;
}
Your program exploits undefined behavior as you modify y multiple times between two sequence points (in your case, the end of the statement). If you turn on warnings with -Wall, your compiler is probably even going to warn you about that.
6+7+6 = 19
so 19 will be your output
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I am new to C, i have an Increment operator program in C
#include<stdio.h>
main(){
int a, b;
a = 2;
b = a + ++a + ++a;
printf("%d", b);
getchar();
}
The output is 10, can someone explain me how the output will be 10 .
a + ++a + ++a;
Behaviour for this is undefined.
The compiler might generated code that evaluated this as 2 + 4 + 4 or 3 + 3 + 4, but any combination/ordering of incrementing and accessing is a "valid" result.
This is undefined, the ++i can happen in any order.
Function call arguments are also ambigiously evaluated, e.g. foo(++i,++i).
Not all operator chains are undefined, a||b||c is guaranteed to be left-to-right, for example.
The guarantees are made in places known as sequence points although this terminology is being deprecated and clarified in C++0x.
What's odd in your example is that neigher 2+3+4 nor 4+4+3 happened, so the compiler evaluated the left side first in one step and the right side first in the other. This was probably an optimisation to flatten the depencency graph.