放置新的和未初始化的POD成员 C++标准保证未初始化的POD成员在放置新的?之后保持它们的先前值吗?

放置新的和未初始化的POD成员 C++标准保证未初始化的POD成员在放置新的?之后保持它们的先前值吗?,c++,initialization,placement-new,C++,Initialization,Placement New,或者更准确地说,根据C++11,是否始终满足以下断言 #include <cstdlib> #include <cassert> struct Foo { int alpha; // NOTE: Uninitialized int beta = 0; }; int main() { void* p = std::malloc(sizeof (Foo)); int i = some_random_integer(); static

或者更准确地说,根据C++11,是否始终满足以下断言

#include <cstdlib>
#include <cassert>

struct Foo {
    int alpha; // NOTE: Uninitialized
    int beta = 0;
};

int main()
{
    void* p = std::malloc(sizeof (Foo));
    int i = some_random_integer();
    static_cast<Foo*>(p)->alpha = i;
    new (p) Foo;
    assert(static_cast<Foo*>(p)->alpha == i);
}
#包括
#包括
结构Foo{
int alpha;//注意:未初始化
intβ=0;
};
int main()
{
void*p=std::malloc(sizeof(Foo));
int i=某个随机整数();
静态(p)->α=i;
新(p)富;;
断言(静态_cast(p)->alpha==i);
}
C++03的答案相同吗?

C++11 12.6.2/8“初始化基和成员”说明:

在非委托构造函数中,如果给定的非静态数据成员或 基类不是由mem初始值设定项id指定的(包括 没有mem初始值设定项列表的情况,因为构造函数 没有ctor初始值设定项),并且实体不是的虚拟基类 一个抽象类(10.4),然后

  • 如果实体是具有大括号或相等初始值设定项的非静态数据成员,则将按照中的指定初始化该实体 8.5;
  • 否则,如果实体是变体成员(9.5),则不执行初始化
  • 否则,实体默认初始化(8.5)
int
上的默认初始化不执行任何操作(8.5/6“初始值设定项”):

默认初始化T类型的对象意味着:

  • 如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(初始化为 如果T没有可访问的默认构造函数,则格式错误)
  • 如果T是数组类型,则每个元素默认初始化
  • 否则,不执行初始化
因此,成员
alpha
应该单独处理

C++标准保证未初始化的POD成员在放置新的?

之后保持它们的先前值吗? 根据C++11,是否始终满足以下断言

#include <cstdlib>
#include <cassert>

struct Foo {
    int alpha; // NOTE: Uninitialized
    int beta = 0;
};

int main()
{
    void* p = std::malloc(sizeof (Foo));
    int i = some_random_integer();
    static_cast<Foo*>(p)->alpha = i;
    new (p) Foo;
    assert(static_cast<Foo*>(p)->alpha == i);
}
否。

未初始化的数据成员有一个不确定的值,这与说底层内存是独立的完全不同

[C++11:5.3.4/15]:
创建类型为
T
的对象的新表达式将该对象初始化如下:

  • 如果省略新的初始值设定项,则对象默认已初始化(8.5);如果未执行初始化,则对象的值不确定
  • 否则,新的初始值设定项将根据8.5的初始化规则进行解释,以进行直接初始化
[C++11:8.5/6]:
默认初始化类型为
T
的对象意味着:

  • 如果
    T
    是一个
    (可能是cv限定的)类类型(第9条),则调用
    T
    的默认构造函数(如果
    T
    没有可访问的默认构造函数,则初始化格式错误)
  • 如果
    T
    是数组类型,则默认初始化每个元素
  • 否则,不执行初始化
[C++11:12.1/6]:
当odr使用它(3.2)创建其类类型(1.8)的对象时,或者当它在第一次声明后显式默认时,默认且未定义为已删除的默认构造函数被隐式定义隐式定义的默认构造函数执行将要初始化的类的初始化集 由用户为该类编写的默认构造函数执行,没有ctor初始值设定项(12.6.2)和空的复合语句。

[C++11:12.6.2/8]:
在非委托构造函数中,如果给定的非静态数据成员或基类
未由mem初始值设定项id指定(包括没有mem初始值设定项列表的情况,因为构造函数没有ctor初始值设定项)实体不是抽象类(10.4)的虚拟基类,那么

  • 如果实体是具有大括号或相等初始值设定项的非静态数据成员,则按照8.5中的规定初始化实体
  • 否则,如果实体是变体成员(9.5),则不执行初始化
  • 否则,实体默认初始化(8.5)
NB.
12.6.2/8
中的第一个选项是如何处理您的会员
beta

[C++11:8.5/6]:
默认初始化类型为
T
的对象意味着:

  • 如果
    T
    是(可能是cv限定的)类类型(第9条),则调用
    T
    的默认构造函数(如果
    T
    没有可访问的默认构造函数,则初始化是错误的)
  • 如果
    T
    是数组类型,则默认初始化每个元素
  • 否则,不执行初始化。
[C++11:8.5/11]:
如果没有为对象指定初始值设定项,则默认初始化该对象如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定值。

编译器可以选择在分配期间将底层内存归零(或以其他方式更改)。例如,众所周知,处于调试模式的Visual Studio会将可识别的值(如
0xDEADBEEF
)写入内存以帮助调试;在本例中,您可能会看到
0xCDCDCDCD
,它们用来表示“干净内存”()

在这种情况下,会吗?我不知道。我认为我们不可能知道

我们知道的是C++并没有禁止它,我相信这会让我们得出这个结论的结论。p>
C++03的答案相同吗

,尽管稍微有点夸张