常量初始化
来自 cppreference.com
将 静态 变量的初始值设置为编译时常量。
内容 |
[编辑] 解释
如果静态 或线程局部(自 C++11 起) 变量进行常量初始化(见下文),则在所有其他初始化之前执行常量初始化,而不是零初始化。
变量或临时对象 obj 如果满足以下条件,则为常量初始化:
- 它有 初始化器,或者它的 默认初始化 导致执行某些初始化,以及
- 它的初始化 完整表达式 是 常量表达式,但如果 obj 是一个对象,则该完整表达式还可以调用 constexpr 构造函数以用于 obj 及其 子对象,即使这些对象属于非 字面量 类类型(自 C++11 起).
常量初始化的效果与相应的初始化的效果相同,只是保证它在任何其他静态 或线程局部(自 C++11 起) 对象的初始化开始之前完成,并且它可以在编译时执行。
[编辑] 注释
如果编译器可以保证值与按标准初始化顺序执行时的值相同,则允许它使用常量初始化来初始化其他静态 和线程局部(自 C++11 起) 对象。
在实践中,常量初始化是在编译时执行的,并且预先计算的对象表示存储为程序映像的一部分(例如在 .data
部分中)。如果变量同时是 const
和常量初始化,则其对象表示可能会存储在程序映像的只读部分(例如 .rodata
部分)中。
[编辑] 示例
运行此代码
#include <iostream> #include <array> struct S { static const int c; }; const int d = 10 * S::c; // not a constant expression: S::c has no preceding // initializer, this initialization happens after const const int S::c = 5; // constant initialization, guaranteed to happen first int main() { std::cout << "d = " << d << '\n'; std::array<int, S::c> a1; // OK: S::c is a constant expression // std::array<int, d> a2; // error: d is not a constant expression }
输出
d = 50
[编辑] 缺陷报告
以下行为变更缺陷报告已追溯应用到之前发布的 C++ 标准。
DR | 应用于 | 发布时的行为 | 正确行为 |
---|---|---|---|
CWG 441 | C++98 | 引用无法进行常量初始化 | 可进行常量初始化 |
CWG 1489 | C++98 | 不清楚是否可以对对象进行值初始化 作为常量初始化 |
可以 |
CWG 1747 | C++98 | 将引用绑定到函数无法进行常量初始化 | 可以 |
CWG 1834 | C++11 | 将引用绑定到右值无法进行常量初始化 | 可以 |
CWG 2026 | C++98 | 零初始化被指定为始终 首先发生,即使在常量初始化之前 |
如果 应用常量初始化,则不进行零初始化 |
CWG 2366 | C++98 | 默认初始化无法进行常量 初始化(需要常量初始化器) |
可以 |