First of all, let us remember than a compiler does not have the same view of the source code as we do: syntax does not matter to it, only semantics. As such, we could argue it has a rather symbolic view of the code.
Furthermore, when the optimizer comes into to play, it will apply analyses and transformations that will turn equivalent symbolic executions into the equivalent binary.
Therefore, what matters for optimization is semantics. There are 3 different syntactic forms that can be used for an if
statement:
// with a temporary
if (make()) { ... } else { ... }
// with a variable already in scope
auto var = make();
if (var) { ... } else { ... }
// with a new variable
if (auto var = make()) { ... } else { ... }
The latter syntax is desugared to:
{ auto var = make(); if (var) { ... } else { ... } }
There is a semantic difference: the scope of those variables differ.
- in the temporary case, its lifetime ends before the
if
orelse
block is executed - in the named variable case, its lifetime ends at the end of its scope, after the
else
thus
In general, the difference of lifetime should be negligible, semantically. There are some cases though where it might matter: if you need to access it or if the side effects need be properly sequenced.
There might be some effects on the emitted code:
- for a built-in type: it is unlikely there will be any effect
- for a POD type: it might not be optimized as clearly
- for a non-POD type: the side-effects in the destructor (such as releasing memory) may inhibit optimizations
And which optimizations ?
Well, the primary optimization that could be applied here is stack reuse, whenever an object's lifetime has ended the compiler should be free to reuse its memory space for another object (see -fstack-reuse
).
If the compiler cannot prove the object is no longer used, or must keep it alive because of side-effects in its destructors, then it might have to occupy more space on the stack for this object. As mentioned, it's unlikely this will occur (with optimizations turned on) when it comes to built-in types, but with a std::string
unfortunately I would not be surprised.