事实上,问题来自于标准草案N4582中的文字:
静态/3允许实现作为静态初始化执行具有静态或线程存储持续时间的变量的初始化,即使这种初始化不需要静态地进行,前提是 -初始化的动态版本不会在初始化之前更改任何其他静态或线程存储持续时间对象的值,以及 -初始化的静态版本在初始化变量中产生的值与动态初始化产生的值相同,如果所有不需要静态初始化的变量都是动态初始化的。
这些词是否意味着,如果满足这两个条件,可以静态地完全初始化类类型的非局部变量(零初始化),从而不调用其构造函数(因为通过调用构造函数初始化的动态版本可能被静态版本所取代)?
发布于 2016-06-11 08:16:11
静态初始化在编译/链接期间执行。编译器/链接器为静态内存中的变量分配一个位置,并用正确的字节填充它(字节不需要全部为零)。当程序启动时,静态内存的这些区域将从程序的二进制文件中加载,不需要进一步初始化。
示例:
namespace A {
// statically zero-initialized
int a;
char buf1[10];
// non-zero initialized
int b = 1;
char date_format[] = "YYYY-MM-DD";
}与静态初始化不同,动态初始化需要在程序启动后运行一些代码,从而将初始化的变量设置为它们的初始状态。需要运行的代码不需要是构造函数调用。
示例:
namespace B {
int a = strlen(A::date_format); (1)
int b = ++a; (2)
time_t t = time(); (3)
struct C {
int i;
C() : i(123) {}
};
C c; (4)
double s = std::sqrt(2); (5)
}现在,C++标准允许编译器执行在动态初始化期间执行的计算,前提是这些计算不会产生副作用。此外,这些计算不能依赖于外部环境。在上面的例子中:
(1)可以静态地执行,因为strlen()没有任何副作用。
(2)必须保持动态,因为它会变异a。
(3)必须保持动态,因为它依赖于外部环境/进行系统调用。
(4)可以静态地进行。
(5)有点棘手,因为浮点计算取决于FPU的状态(即舍入模式)。如果编译器被告知不要认真对待浮点算法,那么它可以静态地执行。
https://stackoverflow.com/questions/37757316
复制相似问题