在某些情况下,如何理解允许实现将非局部变量的动态初始化视为静态初始化? [英] How to comprehend that an implementation is permitted to treat dynamic initialization of non-local variable as static initialization in some cases?

查看:138
本文介绍了在某些情况下,如何理解允许实现将非局部变量的动态初始化视为静态初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实际上,问题出在标准草案N4582中的文字:

In fact, the problem comes from the words in the standard draft N4582:

[basic.start.static/3]允许实现以静态或线程存储持续时间对变量进行初始化,以作为静态初始化,即使这种初始化不是必须静态进行的,只要

[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.

这两个词是否意味着如果满足两个条件,则可以静态地完全初始化类类型的非局部变量(零初始化),以便不调用其构造函数(由于动态版本,因此通过调用构造函数,可以用静态版本代替)?

Do these words mean that if the two conditions are satisfied, a non-local variable of class type may be fully initialized statically (zero-initialized) so that its constructor is not called (since the dynamic version, initializing by calling a constructor, may be replaced by a static version)?

推荐答案

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

Static initialization is performed during compilation/linking. The compiler/linker assigns a location to the variable in the static memory and fills it with the correct bytes (the bytes don't need to be all zeros). When the program starts, those regions of the static memory are loaded from the program's binary file and no further initialization is required.

示例:

namespace A {
    // statically zero-initialized
    int a;
    char buf1[10];

    // non-zero initialized
    int b = 1;
    char date_format[] = "YYYY-MM-DD";
}

与静态初始化不同,动态初始化要求在程序启动后运行一些代码,以将如此初始化的变量设置为初始状态.需要运行的代码不必是构造函数调用.

Unlike static initialization, dynamic initialization requires running some code after program start-up to set thus initialized variables to their initial state. The code that needs to be run doesn't need to be a constructor call.

示例:

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 ++标准允许编译器执行将在动态初始化期间执行的计算,前提是这些计算没有副作用.此外,这些计算不得依赖于外部环境.在上面的示例中:

Now, the C++ standard allows the compiler to perform the computations that would be carried out during dynamic initialization, provided that those computations do not have side effects. Besides, those computations must not depend on external environment. In the above example:

(1)可以静态执行,因为strlen()没有任何副作用.

(1) can be performed statically since strlen() doesn't have any side-effects.

(2)必须保持动态,因为它会突变a.

(2) must stay dynamic since it mutates a.

(3)必须保持动态,因为它取决于外部环境/进行系统调用.

(3) must stay dynamic since it depends on external environment/makes system calls.

(4)可以静态执行.

(5)有点棘手,因为浮点计算取决于FPU的状态(即舍入模式).如果告诉编译器不要认真对待浮点算术,那么它可以静态执行.

(5) is a little tricky, since floating point computation depends on the state of the FPU (namely, rounding mode). If the compiler is told not to treat floating point arithmetic that seriously, then it can be performed statically.

这篇关于在某些情况下,如何理解允许实现将非局部变量的动态初始化视为静态初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆