std::initializer_list 下的数组的生命周期是多少?
What is the lifetime of the array underlying a std::initializer_list?
关注这个答案
我有一个奇怪的行为。
在调试中我得到了预期的输出,但是在发布中(我在 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.
任何人都可以向我解释 debug/release 模式如何影响 initializer_list 底层数组的生命周期吗?
或者对此行为提供一些其他解释。
auto a = wrap({1,2,3});
initializer_list
(及其底层数组)的生命周期在该表达式的末尾结束,因此 a
包含一个悬挂指针。
这意味着 std::cout<< a[2]
有未定义的行为。同样,对于 test
中的代码,std::cout <<
a[1]` 也是未定义的行为。
Can anyone explain to me how debug/release mode influences the lifetime of the initializer_list underlying array ? Or provide some other explanation for this behavior.
这是未定义的行为。
任何事情都可能发生。
在发布模式下,编译器以不同的方式优化事物,因此堆栈上变量的布局不同,因此具有未定义行为的代码可能会做一些不同的事情。或者它可能不会。
这甚至不是 initializer_list
特有的,对于 任何 临时对象,您会得到类似的未定义行为,您将指针指向:
wrap( std::vector<int>(1, 1) );
关注这个答案
我有一个奇怪的行为。
在调试中我得到了预期的输出,但是在发布中(我在 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.
任何人都可以向我解释 debug/release 模式如何影响 initializer_list 底层数组的生命周期吗? 或者对此行为提供一些其他解释。
auto a = wrap({1,2,3});
initializer_list
(及其底层数组)的生命周期在该表达式的末尾结束,因此 a
包含一个悬挂指针。
这意味着 std::cout<< a[2]
有未定义的行为。同样,对于 test
中的代码,std::cout <<
a[1]` 也是未定义的行为。
Can anyone explain to me how debug/release mode influences the lifetime of the initializer_list underlying array ? Or provide some other explanation for this behavior.
这是未定义的行为。
任何事情都可能发生。
在发布模式下,编译器以不同的方式优化事物,因此堆栈上变量的布局不同,因此具有未定义行为的代码可能会做一些不同的事情。或者它可能不会。
这甚至不是 initializer_list
特有的,对于 任何 临时对象,您会得到类似的未定义行为,您将指针指向:
wrap( std::vector<int>(1, 1) );