c++ - 如何理解在某些情况下允许实现将非局部变量的动态初始化视为静态初始化?

标签 c++ static-initialization

其实问题出在标准草案N4582中的话:

[basic.start.static/3] An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that

— the dynamic version of the initialization does not change the value of any other object of static or thread storage duration prior to its initialization, and

— the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.

这句话是不是意味着如果满足这两个条件,一个类类型的非局部变量可能被完全静态初始化(零初始化),这样它的构造函数就不会被调用(动态版本以后,通过调用一个构造函数,可以用静态版本代替)?

最佳答案

静态初始化在编译/链接期间执行。编译器/链接器在静态内存中为变量分配一个位置,并用正确的字节填充它(字节不需要全为零)。当程序启动时,静态内存的这些区域将从程序的二进制文件中加载,不需要进一步的初始化。

例子:

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 的状态(即舍入模式)。如果编译器被告知不要那么认真地对待浮点运算,那么它可以静态地执行。

关于c++ - 如何理解在某些情况下允许实现将非局部变量的动态初始化视为静态初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37757316/

相关文章:

时间:2019-05-17 标签:c++curlundefinedreferenceto_imp__curl_easy_initCodeblocks

c++ - 如何删除排序 vector 中的重复项

c++ - 当我尝试将范围值存储为8位固定宽度整数时,它向我显示了其他一些值[ASCII]

c++ - 在静态初始化期间创建和使用 vector 是否安全?

c++ - 我可以在用 C++ 构造静态本地时访问它吗?

c++ - C++中的静态结构和静态全局变量

c++ - 静态变量的 Constexpr 构造函数导致动态初始化

c++ - 在 C++/CLI 中使用 unique_ptr 时出现链接器错误

c++ - clang 和 gcc 在处理模板生成和静态 constexpr 成员时的不同行为?

c++ - Crypto++ 中的蛇实现