#include <iostream>
#include <vector>
using namespace std;
vector<int> a;
int gen(int x) {
if (!x)
return 0;
int u = a.size();
a.push_back(0); //*/
a[u] = gen(x - 1) + 1; /*/
int t = gen(x - 1) + 1;
a[u] = t; //*/
return a[u];
}
int main() {
gen(10);
for (int x : a)
cout << x << " ";
cout << endl;
return 0;
}
I recently had a non-trivial bug related to std vector. Above is the simplified code to reproduce it. Semantically this should output 10 9 8 7 6 5 4 3 2 1 but actually it doesn't. The problem was here a[u] = gen(x - 1) + 1
. The vector a is reallocated before gen(x - 1)
finish, so the target a[u]
is outdated. Adding a temp variable t
resolves this bug.
Summary: be careful playing with vectors. Never do a[i] = f()
, where f()
could modify vector a
.
And running this code with clang(3.9.1) produces desired output: 10 9 8 7 6 5 4 3 2 1. With any optimization level. This doesn't seem to be UB, is it impementation-defined behavior?
It's UB. Like
a[i]=i++;
My bad, reallocating changes
a
and so it is 'unsequenced modification' — UBSimpler example from
acm.math.spbu.ru/~kunyavskiy/cpp/sol16.cpp
(link):