April 5, 2014
MarkBernstein.org
 

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.