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()?

有帮助吗?

解决方案

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.

其他提示

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.

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.

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top