A C++ Optimization Puzzle
I’ve forgotten a detail of C++ semantics; perhaps a reader can give me a hand.
We have a simple function, Mill, the does a task. We create an object saved
for its side effects: for example, the constructor saves the graphic state and the destructor restores it.
void MyClass::Mill() {
GraphicState saved(albatross,ptarmigan);
doSomething();
}
This is straightforward and idiomatic C++.
Now, let the optimizing compiler into the mix. In principle, it could see that tail call of doSomething and say to itself, “I could avoid a procedure call by inlining doSomething inside Mill.” And so it could. What I think it cannot do, though, and what I think LLVM is doing, is to call the destructor of saved
before it calls doSomething
.
So: am I correct in thinking that the GraphicState destructor should not be called until after doSomething returns? And could LLVM really be doing this wrong? It’s been years – like a decade – since I even smelled a compiler bug.