M.M*_*M.M 6 c++ initialization stdvector undefined-behavior
此代码是否会导致未定义的行为:
#include <vector>
struct S
{
S() {}
int x;
};
int main()
{
std::vector<S> vec(5, S());
}
Run Code Online (Sandbox Code Playgroud)
由于S()默认初始化自动对象,因此其内容不会首先归零,因此x将是不确定的.然后将包含不确定值的对象复制到每个向量位置.
动机:我们可能期望这个行为与std::vector<S> vec(5);不是UB的行为相同(因为C++ 11),所以这是一个容易犯的错误.
正如Praetorian在评论中所提到的,在C++之前,11可以std::vector<S> vec(5);自由地进行5次默认初始化,或者对部分或全部项目使用复制构造函数.
\n\n
TL;DR是的,这是未定义的行为。
\n\n在您的代码中,您对临时值进行初始化:
\n\nstd::vector<S> vec(5, S());\n// ^^^\nRun Code Online (Sandbox Code Playgroud)\n\n来自\xc2\xa78.5/10:
\n\n\n\n\n其初始化器是一组空括号(即 )的对象
\n()应进行值初始化。
值初始化的定义是:
\n\n\n\n\n\xc2\xa78.5/8
\n\n对类型的对象进行值初始化
\n\nT意味着:\n\n\xe2\x80\x94 如果
\n\nT是一个(可能是 cv 限定的)类类型(第 9 条),没有默认构造函数 (12.1) 或用户提供或删除的默认构造函数,则该对象被默认初始化;\xe2\x80\x94 [..]
\n
在这种情况下,值初始化不包括零初始化,因为S有一个用户声明的默认构造函数。所以它是默认构造的。
\n\n\n\xc2\xa78.5/7
\n\n默认初始化类型的对象
\n\nT意味着:\n\n\xe2\x80\x94如果
\n\nT是(可能是 cv 限定的)类类型(第 9 条),则考虑构造函数。枚举适用的构造函数(13.3.1.3),并()通过重载决策选择最适合初始化器的构造函数(13.3)。使用空参数列表调用如此选择的构造函数来初始化对象。\xe2\x80\x94 如果 T 是数组类型,则每个元素都默认初始化。
\n\n\xe2\x80\x94 否则,不执行初始化。
\n
由于您的默认构造函数没有显式初始化x,因此它保留未初始化的垃圾值。默认的复制构造函数使用这些值(即 UB)初始化其他元素。
\n\n\xc2\xa78.5/12
\n\n如果评估产生不确定值,则行为未定义
\n
| 归档时间: |
|
| 查看次数: |
316 次 |
| 最近记录: |