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:
- Assuming
A[1]is evaluated first, you get anint&referring to the second element ofAat that point. - Then, the
func()is evaluated, which can reallocate the storage for the vector, leaving the previously retrievedint&a dangling reference. - Finally, the assignment is performed, writing to unallocated storage. Since the standard allocators cache memory, the OS often won’t catch this error.
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.