Namespaces
Variants

Zero-initialization

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

目录

语法

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

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];   // 零初始化为三个 0.0
int* p;        // 零初始化为空指针值
               //(即使该值不是整数 0)
std::string s; // 零初始化为不确定值,随后
               // 通过 std::string 的默认构造函数默认初始化为 ""
int main(int argc, char*[])
{
    delete p; // 删除空指针是安全的
    static int n = argc; // 先零初始化为 0,再复制初始化为 argc
    std::cout << "n = " << n << '\n';
    A a = A(); // 效果等同于:A a{}; 或 A a = {};
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

可能的输出:

n = 1
a = {0 0 0}

缺陷报告

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

缺陷报告 适用标准 发布时行为 正确行为
CWG 277 C++98 指针可能用值为0的非常量表达式初始化,
但该表达式不是空指针常量
必须用值为0的整型常量表达式初始化
CWG 694 C++98 类类型的零初始化忽略填充位 填充位初始化为零比特
CWG 903 C++98 标量类型的零初始化将初始值设为
从值为0的整型常量表达式转换而来的值
对象被初始化为从整数字面量
0 转换而来的值
CWG 2026 C++98 零初始化被规定为始终最先执行,
甚至先于常量初始化
若适用常量初始化则
不执行零初始化
CWG 2196 C++98 类类型的零初始化忽略基类子对象 基类子对象同样进行零初始化
CWG 2253 C++98 未明确零初始化是否
适用于未命名位域
适用(所有填充位
均初始化为零比特)

参见