Why do un-named C++ objects destruct before the scope block ends?

谁说胖子不能爱 提交于 2019-11-27 04:37:56

A temporary variable lives until the end of the full expression it was created in. Yours ends at the semicolon.

This is in 12.2/3:

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

Your behavior is guaranteed.

There are two conditions that, if met, will extend the lifetime of a temporary. The first is when it's an initializer for an object. The second is when a reference binds to a temporary.

The rules that govern the lifetimes of temporary objects have nothing to do with notion of scope. Scope is a property of a name, and temporary objects do not have names. In other words, temporary objects have no scope.

Most of the time the lifetime of a temporary object ends at the end of the full expression that created that object, which is what you observed in your experiment. This is the general rule that has some exceptions. The main one is that if you immediately attach a reference to your temporary object, the lifetime of the object will be extended to match the lifetime of the reference

const Foo &rfoo = Foo("one");

The above temporary will live as long as rfoo lives.

The scope of a temporary object like that is just one line. Think about it, you can no longer reference it after the line ends, so why would the object remain around?

If this weren't the case, compilers wouldn't be able to optimize out temporary objects in function calls.

Danilo Piazzalunga

Yes, it is desired.

Foo foo("three") creates a normal object which will be destroyed when the scope ends.

Foo("one") creates a temporary object, which is destroyed at the end of the instruction[1]. Why? Because there is no way you can access it after the instruction has ended.

[1] Deliberate simplification: I should have said sequence point.

Because the standards committee goofed. It does it because they chose to make it do it. It's defined to do it this way. It should be considered an anonymous instance with scope the same as if it had been named. From the point of instantiation to the end of the block. Apparently they thought the only use was for passing temporaries into functions where it's pushed on the stack and popped off the stack at the end of a function call...

An unnamed object should still be pushed onto the stack and remain on the stack until the block ends, thus popping it off the stack when expected. Constructing and destructing an object during a single statement is pointless. I'd like to see a single instance/case where this is actually useful. If it doesn't stay in scope for the duration of the block it should most certainly be an error and should at minimum generate a warning.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!