This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
I would always expect that it works as described here: What is x after "x = x++"?
But when I tried to test it:
int x = 0;
x = x++;
printf("x = %d\n", x);
The result is not 0 as I would expect but 1. We tested it in VS2012 and g++ (version 4.7).
Note, that this code prints 0 as expected:
int x = 0;
int y = x++;
printf("y = %d\n", y);
Note that you are linking Java question, but you are writing in C++.
In C (and inherited in C++), x = x++; is undefined, because you are modifying x twice between two sequence points. This means that the code can do literally anything, including stealing money from your bank account and hiring hitmen to kill you, and the compiler is in the right.
Be glad that it only sets x to 1. :-)
Related
This question already has answers here:
Pre vs Post Increment
(3 answers)
Closed 8 months ago.
I have the following c++ program:
#include <iostream>
using namespace std;
//looping through arrays backwards
int main() {
int a[3] {1, 2, 3};
int x = sizeof(a), y = sizeof(int), z = x / y;
for(int i = z - 1; i >= 0; i--) {
cout << a[i] << " ";
}
return 0;
}
And it outputs 3 2 1. But if I change the first parameter in the for loop to int i = z--;, it outpus 2 3 2 1 and I don't understand why. Aren't z - 1 and z-- supposed to be the same thing? Could someone please explain why? Also, I'm a begginer in C++ and I'm learning via the W3Schools tutorial about it. Thanks!
The expression z-- evaluates to z, then - as a side effect - z is decremented (scheduled according to scheduling rules). This means, you're essentially saying int i = z in your loop (and then decrement z, but it's not used anymore) - therefore, your code has UB. The 2 printed is purely coincidental, anything might be printed or anything could happen in your code. If you'd like to use --, use it as prefix, i. e., int i = --z.
This question already has an answer here:
Integer division always zero [duplicate]
(1 answer)
Closed 6 years ago.
Hi so whenever I try to do division such as double x = 3 * (5/10); it will make x = 0 for some reason. Is there a reason this happens in c++ I'm learning and have no clue why this happens.
think about this: what data type is 5?
what data type is 10?
INTEGER!!!
then
(int)5 / (int)10 = (int)0.5 = 0
try this
double a = 3;
double b = 5;
double c = 10;
double x = a * (b/c);
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
In Python, you can easily exchange the values of 2 variables with an expression like this:
x, y = y, x
In C++, on the other hand, if you want to exchange the values of 2 variables, you usually use a temporary variable to store the value of one of your variables, something like this:
int var1 = 100;
int var2 = 200;
int temp = var1;
var1 = var2;
var2 = temp;
This is easy, but you have to write a lot of code.
A professor that I have been following for his lectures on C++ has discovered a new compact way of exchange the values of 2 variables in a magic way:
int x = 200;
int y = 100;
x = y - x + (y = x);
It seems incredible, but it works both with the compiler he's using and mine Apple LLVM version 6.0 (clang-600.0.56).
It seems that the way that expression is interpreted is the following:
(y = x) // returns the value of x
-x + x = 0
x = y + 0
x = y
y = x // finally, y receives the initial value of x
If I try to exchange the values of some variables in a loop, it seems also to work:
for (int i = -10; i <= 10; i++) {
for (int j = 10; j >= -10; j--) {
int x = i, y = j;
x = y - x + (y = x);
std::cout << "x = " << x << "\ny = " << y << '\n';
}
}
We have seen that the exchange is done, but my compiler gives me this warning:
main.cpp:28:22: warning: unsequenced modification and access to 'y'
[-Wunsequenced]
If there's a warning, I suppose this is not a new standard way of exchanging the values of 2 variables, but was just an ingenious workaround of this professor.
Why this method is not standardised in C++, and why exactly does it work?
This is undefined behavior, and it's not guaranteed to work. The order of evaluation of the parameters in an expression is not specified. So it's allowed to access the value of y for the subtraction before or after it performs the y = x assignment.
The reason it's specified like this is to allow flexibility for optimizations.
It "works" because you were unlucky.
Yes, I said unlucky. The code has undefined behavior; the fact that it appears to "work" means that your compiler has let you get away with code that could fail next time you run it.
x = y - x + (y = x);
The object y is accessed twice, once to read its value and once to assign a value to it. The language does not define the order in which those accesses occur -- or that the occur in any order at all. As the warning message says, they're "unsequenced". The possible behaviors are not limited to the two possible orders; the behavior is entirely undefined.
Furthermore, the addition and/or subtraction could overflow, which is another potential source of undefined behavior.
This, `x = y - x + (y = x);, is undefined behavior in C - one undefined behavior listed by the C99 spec is:
Between two sequence points, an object is modified more than once, or
is modified and the prior value is read other than to determine the
value to be stored
The only sequence points in this expression are the beginning of the expression and the end of the complete expression.
This question already has answers here:
Post increment and Pre increment in C
(3 answers)
Closed 9 years ago.
I was expecting this code snippet to print 3 as the if condition is false and y++ will execute, but it prints 2, any idea why..Thanks!!
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x++ : y++);
// This prints 2
x++ and y++ are post-increment. That is, they return the current value of the variable, then add one to it.
Pre-increment would be ++x or ++y. Those increment and then return the new value.
Both pre- and post-increment (and -decrement) are useful things when writing loop controls, which is why C supports both.
(Originally, if I remember correctly, C only supported pre-increment and post-decrement, because there happened to be instructions on the machines it was developed on which encapsulated those behaviors. But as C moved to other systems, and as people started noticing that they wanted both pre and post for both, this was generalized.)
Note that this means the c++ language was misnamed. It should have been called ++c -- we want it improved before we use it, not after!
It's because y++ returns the value of y then increases it.
Where as if you put ++y it would increase the value of y first then return it.
The ++ operators are evaluated last; this is called "post-increment." So, this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x++ : y++);
is equivalent to this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x : y);
y++;
(x++ isn't ever reached because of the ternary condition.) On the other hand, this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? ++x : ++y);
would increment y before returning its respective value to printf(), so the logic would be:
printf("%d\n", (3<2) ? 3 : 3); // prints 3
Since you use a post increment y++, value of y will be used first and incremented. That is the printf will be passed the value before increment operation, in your case y is 2 before increment and 2 will be printed.
You should consider x++ and y++ after all the other operations of this line have been completed. So, print y and then increment x and y.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
I've seen an interesting statement today with post-increment and pre-increment. Please consider the following program-
#include <stdio.h>
int main(){
int x, z;
x = 5;
z = x++ - 5; // increase the value of x after the statement completed.
printf("%d\n", z); // So the value here is 0. Simple.
x = 5;
z = 5 - ++x; // increase the value of x before the statement completed.
printf("%d\n", z); // So the value is -1.
// But, for these lines below..
x = 5;
z = x++ - ++x; // **The interesting statement
printf("%d\n", z); // It prints 0
return 0;
}
What's going on there actually in that interesting statement? The post-increment is supposed to increase the value of x after the statement completed. Then the value of first x is remain 5 for that statement. And in case of pre-increment, the value of second x should be 6 or 7 (not sure).
Why does it gives a value of 0 to z? Was it 5 - 5 or 6 - 6? Please explain.
It's Undefined Behavior. The compiler is free to do whatever it wants -- it may give 0, it may give 42, it may erase your hard drive, or it may cause demons to fly out of your nose. All of those behaviors are permitted by the C and C++ language standards.