Weird behavior of reference to vector.back() after vector is modified

c++, c++11, reference, vector

Solution

push_back can cause reallocation, if we look at the draft C++ standard section `23.3.6.5` vector modifiers says:

void push_back(const T& x);

void push_back(T&& x);

Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid.

we can see that back gives us a reference and so if there is a reallocation it will not be valid anymore.

Problem

Let's start with this sample code in C++: ``` #include <vector> #include <iostream> int main() { std::vector<int> vec; vec.push_back(0); for (int i = 1; i < 5; i++) { const auto &x = vec.back(); std::cout << "Before: " << x << ", "; vec.push_back(i); std::cout << "After: " << x << std::endl; } return 0; } ``` The code is compiled with `g++ test.cc -std=c++11 -O0` and below is the result: ``` Before: 0, After: 0 Before: 1, After: 0 Before: 2, After: 2 Before: 3, After: 3 ``` I was expecting the second line of output to be ``` Before: 1, After: 1 ``` since `x` is reference to an item in the vector, which shall not be modified by appending items to the vector. However I haven't read the disassembled code or done any other investigations for now. Also I don't know whether this is an undefined behavior in the language standard. I want this to be explained. Thanks.

Original source