Life time of an unnamed temporary constructed in if condition expression
c++
Solution
As far as I can tell, Visual C++ is wrong in this regard.
Indeed, a temporary is (almost always) destroyed at the end of the full expression in which it is created:
§12.2/3: [...]Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created
Looking at the definition of a selection statement (`if` and `switch`), we can see that the condition is an expression:
§6.4:
selection-statement:
if ( condition ) statement
if ( condition) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq declarator = assignment-expression
So any temporaries created in the condition should be destroyed before executing the following statement (unless bound to a reference-to-const).
The behavior when introducing a new name in the condition is specified in §6.4/3:
A name introduced by a declaration in a condition [...] is in scope from its point of declaration until the end of the substatements controlled by the condition.
So in your example, `x` is in scope in the two branches of the `if`, and destroyed before evaluating `nextInstruction()`.
Problem
How Standard defines the life time of a temporary object constructed during evaluation of an `if` condition expression? I looked for this information and found something similar in an example to point [10] in $1.9, page 10. (I'm referring here to Final Draft of the new specification.) Yet still it wasn't clear (enough) for me and since Visual C++ acted differently than my understanding of that example I decided to ask. Please provide proper references to specification. If you name the object it persists for the entire `if` (so both `true` block and `false` block but is destroyed before `if` ends). For example: ``` if ( MyClass x = f() ) { /* ... */ } else { /* ... */ } nextInstruction(); ``` `x` can be used in both `if` blocks but gets destroyed before `nextInstruction` gets called. But what if you don't name it? ``` if ( f() ) { /* ... */ } else { /* ... */ } nextInstruction(); ``` In my understanding of the referenced part of specification the value returned by `f()` will be destroyed before execution enters one of the blocks (either for `true` or for `false`). However Visual C++ destroys that temporary object as if it was named. (EDIT: as Tino Didriksen pointed out Visual C++ does work well here. And indeed now I confirm that as well. I must have made a mistake when looking at initial tests results!) This does matter in some edge cases (lets not discuss here how likely they are or whether it is good to write code that way...). For example lets have: ``` class ScopedLock { public: ~ScopedLock() { if ( isLocked() ) unlock(); } operator bool() const { return isLocked(); } /* ... */ }; ``` Now if we have code like: ``` if ( ScopedLock lock = resource.lock() ) { /* ... */ } ``` we can be sure that when execution enters the `true` block we own the resource and that it will not be unlocked before we leave that block. But what if someone wrote it like this: ``` if ( resource.lock() ) { /* ... */ } ``` Now it is crucial at which point the destructor for the temporary `ScopedLock` will be called. Because it determines whether this code is correct or not (in the sens of resource usage). (Again lets skip discussing whether writing such code is bad in general. That is not the point of this question...)