I have a program which compiles and runs properly when no -O
flags are set.
When I try building with -Og
, the program complains of a pure virtual function being called and crashes.
I was trying to track this down, so I used the command
g++ -Og -Q --help=optimizers
to get a list of optimizations that -Og
turns on. This gave me a list of 83 different optimization flags that are supposedly enabled. (Curiously, I still get 58 optimizations if I supply -O0
instead of -Og
.)
I tried building with this list of optimizations instead of -Og
directly, with the idea that I'd use a binary search to find the offending optimizations. To my surprise, what happened instead was that the program functioned correctly!
Question: Am I doing something wrong when I'm getting the list of enabled optimizations? Or does the -Og
flag have other effects?
Bonus details
Unfortunately I haven't been able to strip the program I'm compiling down to a minimal working example. Whatever this is seems fairly delicate, and the problem goes away if, for instance, I add a cout
inside of a constructor. However, to give a basic sketch of what's going on here:
- There's a base class with a pure virtual method.
- The base-class constructor calls
std::bind(&Base::virtual_method, this)
and provides this as a callback to another object. - The derived class implements the virtual method.
- The derived class constructor has some member initializers but no code in the constructor body.
- If I put code in the constructor body that can't be optimized out, e.g. a
cout
, then everything works as expected.
So I'm guess the part of the derived class constructor that populates the vtable pointer is being optimized out for some reason. (I haven't manually checked the generated assembly because I haven't figured out how to do it yet.)