命名空间
变体
操作

零初始化

来自 cppreference.com
< cpp‎ | 语言
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直到 C++17*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储持续时间说明符
初始化
 
 

将对象的初始值设置为零。

内容

[编辑] 语法

请注意,这不是零初始化的语法,该语法在语言中没有专门的语法。这些是其他类型的初始化的示例,这些初始化可能会执行零初始化。

static T object ; (1)
T () ;

T t = {} ;

T {} ; (自 C++11 起)

(2)
CharT array [ n ] = " short-sequence "; (3)

[编辑] 解释

在以下情况下会执行零初始化

1) 对于每个具有静态 或线程局部(自 C++11 起) 存储持续时间 且未经 常量初始化 的命名变量,在任何其他初始化之前。
2) 作为 值初始化 序列的一部分,用于非类类型,以及用于值初始化的类类型的成员,这些成员没有构造函数,包括对没有提供初始化器的 聚合 的元素的值初始化。
3) 当任何 字符类型 的数组用 字符串字面量 初始化且该字面量太短时,数组的剩余部分将进行零初始化。

零初始化的效果是

  • 如果 T标量类型,则该对象将被初始化为通过 显式转换 整数字面量 0(零)到 T 获得的值。
  • 如果 T 是非联合类类型
  • 所有 填充位 将被初始化为零位,
  • 每个非静态 数据成员 将进行零初始化,
  • 每个非虚基类 子对象 将进行零初始化,并且
  • 如果该对象不是基类子对象,则每个 虚基类 子对象将进行零初始化。
  • 如果 T 是联合类型
  • 所有填充位将被初始化为零位,并且
  • 对象的第一个非静态命名数据成员将进行零初始化。
  • 如果 T 是数组类型,则每个元素将进行零初始化。
  • 如果 T 是引用类型,则不会执行任何操作。

[编辑] 注释

非局部初始化 中所述,未经常量初始化的静态 和线程局部(自 C++11 起) 变量将在任何其他初始化之前进行零初始化。如果非类非局部变量的定义没有初始化器,则默认初始化将不执行任何操作,保留之前零初始化的结果不变。

零初始化的指针是其类型的空指针值,即使空指针的值不是整数零。

[编辑] 示例

#include <iostream>
#include <string>
 
struct A
{
    int a, b, c;
};
 
double f[3];   // zero-initialized to three 0.0's
 
int* p;        // zero-initialized to null pointer value
               // (even if the value is not integral 0)
 
std::string s; // zero-initialized to indeterminate value, then
               // default-initialized to "" by the std::string default constructor
 
int main(int argc, char*[])
{
    delete p; // safe to delete a null pointer
 
    static int n = argc; // zero-initialized to 0 then copy-initialized to argc
    std::cout << "n = " << n << '\n';
 
    A a = A(); // the effect is same as: A a{}; or A a = {};
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

可能的输出

n = 1
a = {0 0 0}

[编辑] 缺陷报告

以下更改行为的缺陷报告已追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
CWG 277 C++98 指针可能使用值为 0 的非常量表达式进行初始化,这并非空指针常量
指针使用值为 0 的非常量表达式进行初始化,这并非空指针常量
必须用一个值为0的整型常量表达式进行初始化
常量表达式,值为0
CWG 694 C++98 类类型的零初始化忽略填充 填充被初始化为零位
CWG 903 C++98 标量类型的零初始化将初始值设置为
从值为0的整型常量表达式转换而来的值
对象被初始化为
从整数字面量0转换而来的值
CWG 2026 C++98 零初始化被指定为始终
首先发生,甚至在常量初始化之前
如果
应用常量初始化,则不会进行零初始化
CWG 2196 C++98 类类型的零初始化忽略基类子对象 它们也会被零初始化
CWG 2253 C++98 尚不清楚零初始化是否
应用于无名位域
它适用(所有填充位
被初始化为零位)

[编辑] 另请参阅