默认情况下初始化时 POD 是否给予特殊处理 (C++14)?

are POD given special treatment when default initializing (c++14)?

本文关键字:处理 C++14 初始化 情况下 POD 是否 默认      更新时间:2023-10-16

为什么以下代码生成 0 作为输出?在我的理解中,它是默认初始化(不是值初始化),因此值应该是随机的。

#include <stdio.h>
#include<iostream>
#include<memory>
using namespace std;
struct A 
{
int i;
int j;
};

int main()
{
A a;
cout << " i is " << a.i << endl;
return 0;
}

从 CPP 首选项:

默认初始化的效果如下:

如果 T 是非 POD(直到 C++11)类类型,则考虑构造函数并针对空参数列表进行重载解析。调用所选构造函数(默认构造函数之一)以提供新对象的初始值;

如果 T 是数组类型,则数组的每个元素都是默认初始化的;

否则,不执行任何操作:具有自动存储持续时间的对象(及其子对象)初始化为不确定值。

你得到什么值a.i没有定义,你应该期望得到任何值。

在系统上点胶,使用的标准库,编译器,编译器标志,...内存的某些部分(例如堆栈)可能会用0初始化,但不能保证这一点。

对于gcc也是如此,在您的简单示例中,您可能总是会得到0,但是如果您关闭优化-O0并编译以下代码:

#include <iostream>
struct A 
{
int i;
int j;
};

int foo() {
A a;
const int b = a.i;
a.i = 123;
return b;
}
int main() {
const int n1 = foo();
const int n2 = foo();
std::cout << n1 << " " << n2 << std::endl;
return 0;
}

然后(取决于操作系统,标准库,cpu...)您将有以下输出:

0 123

在这两种情况下,a.i都是未初始化的,对于第一次调用,a.i持有一些"随机">号码,对于第二次调用,a可能在同一位置创建,并且截至此,这部分内存可能仍然保存123。原因是A是在堆栈上创建的,随后对 offfoo的调用很可能会导致a位于堆栈上的同一内存地址上。

基于讨论,实验。这是未定义的行为。POD 在默认初始化中没有特殊处理。

clang,MSVC总是给出随机值,但gcc总是给出0。毕竟,未定义就是未定义。