This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Unsequenced value computations (a.k.a sequence points)
(2 answers)
Closed 8 years ago.
I recently wanted to get a better feeling for the return values of the ++i and the i++ operator. So I created this small program here:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
int j = 0;
cout << "i++ " << i++ << " i " << i << endl;
cout << "++j " << ++j << " j " << j << endl;
}
Now looking at the code I would expect that when I execute it I get the following result:
i++ 0 i 1
++j 1 j 1
Compiling the above snippet with llvm/clang 3.5 (Apple LLVM version 6.0 (clang-600.0.51)) yields the following warning:
main.cpp:8:23: warning: unsequenced modification and access to 'j'
[-Wunsequenced]
cout << "++j " << ++j << " j " << j << endl;
^ ~
1 warning generated.
What does that mean in this context? The only blog post I found was not so helpful since I can't imagine a reordering of the output somehow.
What would the output of such a reordering look like?
There's also a couple of similar questions here. The only good question on the subject I found was this one. But I don't understand how this would create the compiler warning above.
Compiling the code from above with gcc 4.9 (the flag -std=c++11 was enabled) didn't show this warning at all.
Related
This question already has answers here:
Unexpected order of evaluation (compiler bug?) [duplicate]
(3 answers)
Undefined behavior and sequence points
(5 answers)
Closed 6 years ago.
I came across this piece of code:
#include <iostream>
int main()
{
int m = 44;
std::cout << "m = " << m << ", m++ = " << m++ << ", ++m = " << ++m <<
std::endl;
return 0;
}
My first thought was, this is undefined behavior, but it turns out this code was part of an exam in my university, so I'm not so sure now.
The question on the exam is: what is the output of this program?
I also heard that C++11 or C++14 changed the rules about UB in some way, so it might be defined now.
Anyway, the output is (on gcc in windows)
m = 46, m++ = 45, ++m = 46
Is that output correct?
This question already has answers here:
Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
(1 answer)
Does initialization entail lvalue-to-rvalue conversion? Is `int x = x;` UB?
(4 answers)
Closed 6 years ago.
I am confused about the following code:
#include <iostream>
int i = 1;
int main()
{
int i = i;
std::cout << "i: " << i << "\n";
return 0;
}
Output:
i: 0
I had expected running the above code would print 1. Can someone please explain the reason for this strange behavior?
You are initializing i with itself. The both i's in int i = i; are the inner one not the outer one. This is undefined behavior and you may get 0 or anything may happen.
This is the right way if you want to assign the outer i to the inner i.
#include <iostream>
int i = 1;
int main()
{
int i = ::i;
std::cout << "i: " << i << "\n";
return 0;
}
Live Demo
BTW, You should carefully read all the compiler warnings. If you did you could see the problem yourself:
warning 'i' is used uninitialized in this function
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I have this code:
#include <iostream>
using namespace std;
int & squareRef(int );
int main() {
int number1 = 8;
cout << "In main() &number1: " << &number1 << endl;
int & result = squareRef(number1);
// cout << "In main() &result: " << &result << endl;
cout << result << endl;
cout << result << endl;
cout << number1 << endl;
}
int & squareRef(int rNumber) {
cout << "In squareRef(): " << &rNumber << endl;
rNumber *= rNumber;
return rNumber;
}
The program produces the following output:
In main() &number1: 0x28ff08
In squareRef(): 0x28fef0
64
1875681984
8
Can anyone please explain why the two "results" are different , is that suppose to be same isn't ?
You are invoking undefined behaviour by returning a reference to a local variable:
test.cc:19:7: error: reference to local variable ‘rNumber’ returned [-Werror=return-local-addr]
int & squareRef(int rNumber) {
rNumber is copied on the stack for the call. After the call, the value on the stack is undefined, and might well change due to subsequent calls. The reference you return only points to that location on the stack and does not hold the actual value.
In general, when these things happen, it is very helpful to turn on all warnings your compiler can give you. With gcc, the flags -Wall -Wextra -Werror provide you with a lot of helpful warnings, such as these. In general, code should compile without throwing any warnings (except maybe unused variables/parameters in function stubs, although there are macros to explicitly skip over these).
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Undefined behavior and sequence points
(5 answers)
Closed 9 years ago.
Why the output of next code is 2 1 2?
#include "iostream"
int main(int argc, const char *argv[])
{
int i = 0;
std::cout << i << std::endl << i++ << std::endl << ++i << std::endl;
return 0;
}
Because first i is equal 2 but not zero, it means that the whole like of cout is evaluated first
and then printed (not part by part). If so, then first value should be 1, but not 2, because i++ should increment i after printing. Could you clarify?
EDIT:
The output of next code is 2 2 0.
#include "iostream"
int main(int argc, const char *argv[])
{
int i = 0;
std::cout << i << std::endl << ++i << std::endl << i++ << std::endl;
return 0;
}
why?
There is no sense reasoning in the output of your code because as it stands your program exhibits Undefined Behavior.
Per paragraph 1.9/15 of the C++11 Standard:
The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
Because there is no sequence point separating both mutations of i, Undefined Behavior ensues. Your compiler might not output anything, and the program might output differently on different compilers. But arguing about the output is unnecessary in this context.
If you separate the statements, the result will then come out as expected:
std::cout << i << std::endl; // 0
std::cout << i++ << std::endl; // 0
std::cout << ++i << std::endl; // 2
the evalution goes from right to left.
i = 0
++i -> i = 1
i++ -> i = 1, post incrementation, a copy occurs. then i = 2
i -> i = 2
As all this occurs before being send to cout, the value of i is 2, and the middle one have been copied and its value is 1.
Please tell me if I don't understand your question clearly:
cout << i++;
is the equivalent of
cout << i;
i+=1;
while cout << ++i
is the equivalent of
i += 1;
cout << i;
in otherwords any time you use i++, post-increment it returns the current value then changes while ++i means increment first then return the new value. It has nothing to do with cout
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
The variable i is changed twice, but is the next example going to cause an undefined behaviour?
#include <iostream>
int main()
{
int i = 5;
std::cout << "before i=" << i << std::endl;
++ i %= 4;
std::cout << "after i=" << i << std::endl;
}
The output I get is :
before i=5
after i=2
Yes, it's undefined. There is no sequence point on assignment, % or ++ And you cannot change a variable more than once within a sequence point.
A compiler could evaluate this as:
++i;
i = i % 4;
or
i = i % 4;
++i;
(or something else)