Reputation: 3765
result_t work(resource_t& resource) {
lock_t ___(resource);
return work_impl(resource);
}
Is it guaranteed that the destructor of ___
will be called AFTER work_impl()
returned? Or is the compiler free to destroy ___
before calling work_impl()
?
Upvotes: 2
Views: 234
Reputation: 158469
The behavior of this program is actually undefined, the identifier __
is reserved and we can see from the draft C++ standard 17.6.4.3
Reserved names paragraph 2 says:
If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.
and if we look further to section 17.6.4.3.2
Global names which says:
Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
so unless the compiler documents that __
is free to be used by user code then it is reserved.
Destructors are invoked implicitly
So if this program did not invoke undefined behavior the rules for destructors that are invoked implicitly can be taken from the draft standard section 12.4
Destructotrs paragraph 11 which says (emphasis mine)
— for constructed objects with static storage duration (3.7.1) at program termination (3.6.3),
— for constructed objects with thread storage duration (3.7.2) at thread exit,
— for constructed objects with automatic storage duration (3.7.3) when the block in which an object is created exits (6.7),
— for constructed temporary objects when the lifetime of a temporary object ends (12.2),
so that means the destructor for an automatic object will be invoked when you exit work()
, which has to happen after the results are returned. We can see further that the order of objects are destroyed in is also specified from 6.6
Jump statements:
On exit from a scope (however accomplished), objects with automatic storage duration (3.7.3) that have been constructed in that scope are destroyed in the reverse order of their construction. [ Note: For temporaries, see 12.2. —end note ]
Note that names that contain a double underscore __
, or start with either an underscore followed by an uppercase letter are reserved in any scope.
Upvotes: 1
Reputation: 56479
Expression work_impl(resource)
will be executed, the result will be copied to caller side or used as a temporary. Then, Object ___
will be destructed.
On the other hand, DON'T use __
or ___
as prefix of any identifier. They're reserved for compiler.
Upvotes: 4
Reputation: 153909
If the destructor is non-trivial, it may not be called
prematurely, provided that the rest of the code is correct. In
case of undefined behavior (say, a variable name with two or
more adjacent _
), of course, there are no guarantees.
Upvotes: 2
Reputation: 41474
The compiler is free to do whatever it likes if there's no way to tell the difference. But if the destructor has some program-visible effect, it will always happen AFTER work_impl
returns.
Upvotes: 1