lifetime of a std::initializer_list return value

穿精又带淫゛_ 提交于 2019-11-27 14:18:49

The wording you refer to in 8.5.4/6 is defective, and was corrected (somewhat) by DR1290. Instead of saying:

The lifetime of the array is the same as that of the initializer_list object.

... the amended standard now says:

The array has the same lifetime as any other temporary object (12.2 [class.temporary]), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.

Therefore the controlling wording for the lifetime of the temporary array is 12.2/5, which says:

The lifetime of a temporary bound to the returned value in a function return statement is not extended; the temporary is destroyed at the end of the full-expression in the return statement

Therefore the noisydt objects are destroyed before the function returns.

Until recently, Clang had a bug that caused it to fail to destroy the underlying array for an initializer_list object in some circumstances. I've fixed that for Clang 3.4; the output for your test case from Clang trunk is:

destroyed
destroyed
destroyed
received
destroyed
destroyed
destroyed
received

... which is correct, per DR1290.

std::initializer_list is not a container, don't use it to pass values around and expect them to persist

DR 1290 changed the wording, you should also be aware of 1565 and 1599 which aren't ready yet.

Then the return value's array should also survive into the calling function, and it should be possible to preserve it by binding it to a named reference.

No, that doesn't follow. The array's lifetime doesn't keep being extended along with the initializer_list. Consider:

struct A {
    const int& ref;
    A(const int& i = 0) : ref(i) { }
};

The reference i binds to the temporary int, and then the reference ref binds to it as well, but that doesn't extend the lifetime of i, it still goes out of scope at the end of the constructor, leaving a dangling reference. You don't extend the underlying temporary's lifetime by binding another reference to it.

Your code might be safer if 1565 is approved and you make il a copy not a reference, but that issue is still open and doesn't even have proposed wording, let alone implementation experience.

Even if your example is meant to work, the wording regarding lifetime of the underlying array is obviously still being improved and it will take a while for compilers to implement whatever final semantics are settled on.

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