std::initializer_list 下的数组的生命周期是多少? [复制]
Posted
技术标签:
【中文标题】std::initializer_list 下的数组的生命周期是多少? [复制]【英文标题】:What is the lifetime of the array underlying a std::initializer_list? [duplicate] 【发布时间】:2015-03-16 12:43:02 【问题描述】:按照这个答案https://***.com/a/29074955/1098041
我有一种奇怪的行为。
在调试中我得到了预期的输出,但是在发布中(我在 Windows 上使用 mingw)我在 test
函数中得到了垃圾。
#include <iostream>
#include <initializer_list>
template <class T>
struct array
T *ptr;
size_t len;
array() clear();
array( T *p, size_t l ) assign(p,l);
inline void clear() ptr=nullptr; len=0;
inline void assign( T *p, size_t l ) ptr=p; len=l;
inline T& operator[] ( size_t i ) const return ptr[i];
;
template <class T>
inline array<const T> wrap( std::initializer_list<T> lst )
return array<const T>( lst.begin(), lst.size() );
void test( int a, int b, int c )
auto ar = wrap(a,b,c);
std::cout<< ar[1] << std::endl;
int main()
auto a = wrap(1,2,3);
std::cout<< a[2] << std::endl;
test(1,2,3);
调试输出:
3
3
发布中的输出:
3
2686868 // some garbage.
谁能向我解释调试/发布模式如何影响 initializer_list 底层数组的生命周期? 或者为这种行为提供一些其他解释。
【问题讨论】:
可能与Strange values in a lambda returning initializer_list有关 我最初创建了这个问题,因为我发现一个奇怪的行为与问题中链接的已接受答案相矛盾,我被要求提供一个最小示例来重现我的行为。我最初虽然这是一个单独的问题,但似乎这两个问题的答案是矛盾的。现在怎么办 ?请版主帮忙。 【参考方案1】: auto a = wrap(1,2,3);
initializer_list
(及其底层数组)的生命周期在该表达式的末尾结束,因此 a
包含一个悬空指针。
这意味着std::cout<< a[2]
具有未定义的行为。同样对于test
中的代码,std::cout <<
a[1]` 也是未定义的行为。
谁能向我解释调试/发布模式如何影响 initializer_list 底层数组的生命周期?或者为这种行为提供一些其他解释。
这是未定义的行为。
任何事情都有可能发生。
在发布模式下,编译器对事物的优化方式不同,因此堆栈上的变量布局不同,因此具有未定义行为的代码可能会执行不同的操作。或者它可能不会。
这甚至不是特定于 initializer_list
,对于您保存指针的 any 临时对象,您会得到类似的未定义行为:
wrap( std::vector<int>(1, 1) );
【讨论】:
所以我在main
中得到一个有效输出,但在test
中得到一个无效输出是 UB 吗?还是与第一种情况下底层数组是 constexpr 而第二种情况下它是从变量构建的事实有关?
未定义的行为意味着任何事情都可能发生!未定义的行为并不意味着它总是打印垃圾! “我得到了预期的输出”是一种可能的结果,但这并不能改变它未定义且您的程序有问题的事实。
是的,很公平。为什么一个有效而另一个无效并不重要,它是UB。顺便说一句,这个答案与我在问题中链接的公认答案完全矛盾。我虽然这是一个单独的问题,但您的回答似乎表明它不是。我要删除这个问题吗?
我已经发布了另一个问题的新答案。我认为没有任何实际需要删除此问题,但这取决于您。
为什么他有一个悬空指针?他用array<const T>( lst.begin(), lst.size() );
复制初始化列表中的数据。以上是关于std::initializer_list 下的数组的生命周期是多少? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::min(std::initializer_list<T>) 按值接受参数?
为啥 std::initializer_list 不是内置语言?