When the function involves reallocation, I found some compilers may save the address before the function call. It leads the return value stored in the invalid address.
There is an example to explain behavior in above description.
#include <stdio.h> #include <vector> using namespace std; vector<int> A; int func() { A.push_back(3); A.push_back(4); return 5; } int main() { A.reserve(2); A.push_back(0); A.push_back(1); A[1] = func(); printf("%d\n", A[1]); return 0; }
There are some common C++ compiler, and the test result as follows.
1
5
5
Is it undefined behavior?
The behaviour is undefined in all C++ versions before C++17. The simple reason is that the two sides of the assignment operator can be evaluated in any order:
A[1]
is evaluated first, you get an int&
referring to the second element of A
at that point.func()
is evaluated, which can reallocate the storage for the vector, leaving the previously retrieved int&
a dangling reference. Only in C++17, the special rule 20 for the assignment was made:
In every simple assignment expression E1=E2 and every compound assignment expression E1@=E2, every value computation and side-effect of E2 is sequenced before every value computation and side effect of E1
With C++17, A[1]
must be evaluated after the call to func()
, which then provides defined, reliable behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With