This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 8 years ago.
Any reason for the following aberration?
Consider the following C program (named PstFixInc.c)
#include <stdio.h>
int main (int argc, char *argv [])
{
int num = 0;
num = (num++) % 4;
printf ("num: %d\n",num);
return 0;
}
If compiled with gcc 4.8.1:
gcc -o PstFix.exe PstFixInc.c
and then executed, you get the result:
num: 0
If compiled with Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
cl PstFixInc.c
and then executed, you get the result:
num: 1
What you have is undefined behavior, you are modifying num and using its previous value other than to determine the value to be stored within the same sequence point. This is covered in the draft C99 standard section 6.5 paragraph 2 which says:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an
expression.72) Furthermore, the prior value shall be read only to
determine the value to be stored.73)
There are also two examples of undefined behavior:
i = ++i + 1;
a[i++] = i;
The first one is pretty similar to your example.
Using clang even gives you a nice warning:
warning: multiple unsequenced modifications to 'num' [-Wunsequenced]
num = (num++) % 4;
~ ^
This is undefined behavior.
You're assigning to the same variable twice without an interleaving sequence point.
This line:
num = (num++) % 4;
is undefined behavior per the C standard. Any result that the code produces is "correct".
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 months ago.
`
a = 10;
int *ptr = &a;
printf("%d %d\n", a, ++*ptr);
`
The output is - 11 11
How is it evaluated??
This is undefined behaviour, so the result could be anything. There is no sequence point in the line, which means that both operations are unsequenced - either argument could be evaluated first, or both simultaneously (see https://en.wikipedia.org/wiki/Sequence_point and John Bollinger's comment).
For example, when evaluating with the clang compiler, this is the output:
<source>:5:26: warning: unsequenced modification and access to 'a' [-Wunsequenced]
printf("%d %d\n", a, ++a);
~ ^
1 warning generated.
Execution build compiler returned: 0
Program returned: 0
2 3
See this answer for more: Order of operations for pre-increment and post-increment in a function argument?
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 3 years ago.
I know it is theoretically undefined behavior and of course bad style. This is the example of a school (I am not the pupil).
But why do I get 7 (example a) resp. 1 (example b) out of this operation:
Online example:
https://onlinegdb.com/B172lj8k8
a:
#include <stdio.h>
int main()
{
int i = 2;
printf("%d; i=%d", ++i + i++, i);
return 0;
}
b:
#include <stdio.h>
int main()
{
int i = 2;
printf("%d; i=%d", ++i - i++, i);
return 0;
}
In my opinion the output should be 6 and 2.
Execute i++, yield 2, increment i
Execute ++i yield 4
Additon 2 + 4
The other example should be 4 - 2.
Exexcuting the increment in a statement seems to yield the result of the increment immediately, no matter if it is postfix or prefix, which is odd. Or do I get it wrong totally?
The order in which the arguments passed to a function are evaluated is not specified, and the order of evaluating the operants of + is unspecified, too.
So in printf("%d %d", i+1, i-1), for example, you cannot rely on the order of evaluation of the arguments; i+1 might be evaluated after i-1, actually; You will not recognise, since the evaluation of the one does not effect the result of the other.
In conjunction with "side effects" like the post-increment i++, however, the effect of incrementing i at a specific point in time might influence the result of other evaluations based on i. Therefore, it is "undefined behaviour" in C, if a variable is used more than once in an expression and a side effect changes its value (formally, to be precise, if there is no sequence point in between).
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?
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