常量初始化

来自cppreference.com
< cpp‎ | language

设置静态变量的初值为编译时常量。

解释

如果静态或线程局部 (C++11 起)变量以常量被初始化(见下文),那么就会在其他所有初始化之前进行常量初始化以取代零初始化。

变量或临时对象 obj 在满足以下所有条件时会 以常量被初始化

常量初始化的效果与其所对应的初始化的效果相同,但保证它在任何其他静态或线程局部 (C++11 起)对象的初始化前完成,并可能在编译时进行。

注解

编译器也可以对其他的静态及线程局部 (C++11 起)对象进行常量初始化,前提是它可以保证它们的值与遵循初始化的标准顺序时的结果相同。

实践中,常量初始化在编译时进行,并将预先计算的对象表示作为程序映像的一部分(如 .data 段)存储。如果变量既为 const 又被常量初始化,那么它的对象表示可存储于程序映像的只读段(如 .rodata 段)。

示例

#include <iostream>
#include <array>
 
struct S
{
    static const int c;
};
 
const int d = 10 * S::c; // 非常量表达式:此 S::c 前没有初始化器,此初始化在常量初始化之后发生
const int S::c = 5;      // 常量初始化,保证首先发生
 
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK:S::c 是常量表达式
//  std::array<int, d> a2;    // 错误:d 不是常量表达式
}

输出:

d = 50

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
CWG 441 C++98 不能常量初始化引用 使得可常量初始化
CWG 1489 C++98 不明确对象的值初始化是否可以是常量初始化 可以是
CWG 1747 C++98 绑定引用到函数不是常量初始化 可以是
CWG 1834 C++11 绑定引用到亡值不是常量初始化 可以是
CWG 2026 C++98 曾指定始终首先进行零初始化,甚至在常量初始化之前 适用常量初始化时不会进行零初始化
CWG 2366 C++98 默认初始化不是常量初始化(需要常量初始化器) 可以是

参阅