The following minimal-ish program segfaults when compiling with -O3
and perhaps with -O2
, but executes fine with -O0
(with clang 4.0):
#include <iostream>
class A {
public:
virtual void me() const { std::cerr << "hi!\n"; }
};
class B {
public:
B(const A& a_) : a(a_) {}
virtual void me() const { a.me(); }
private:
const A& a;
};
class C {
public:
C(const B& b_) : b(b_) {}
void me() const { b.me(); }
public:
const B& b;
};
int main() {
C c = C(A());
c.me();
}
The reason is that c.b
is initialized with a reference to a temporary object of class B
that is constructed from a temporary A
. After the constructor c.C()
exits, the temporary B
is gone but the reference to it remains in c.b
.
What good practices can I employ to avoid this situation, given that I don't control the implementation of B
or A
? Are there static analyzers that are able to detect this condition? (My version of scan-build
did not find the problem.)