首先,让我们看一下标准(C ++ 14 [basic.start.init] 3.6.3 / 4):
由实现定义,是否在main的第一条语句之前完成具有静态存储持续时间的非局部变量的动态初始化。如果初始化延迟到main的第一条语句之后的某个时间点,则它应发生在与要初始化的变量在同一转换单元中定义的任何函数或变量的第一次odr使用(3.2)之前。
volatile
说明符意味着可以从外部源修改变量。但是,如果不能保证初始化时,可能会在外部修改变量,然后再进行动态初始化。还是存在volatile关键字时,它的工作方式有所不同吗?
以下是我所谈论的示例:在myfile.h中
#ifndef MYFILE_H_ #define MYFILE_H_ int my_init (); #endif /* MYFILE_H_ */
在myfile.cpp中
#include <myfile.h> #include <iostream> int my_init () { std::cout << "init" << std::endl; return 1; } static volatile int my_var __attribute__((unused)) = my_init();
在main.cpp中
#include <myfile.h> #include <iostream> int main() { std::cout << "main" << std::endl; // Let's assume first odr-use of my_var or my_init happens down here, maybe // in a function from another translation unit. return 0; }
假设my_init是一个将my_var设置为有效默认状态的函数,以防万一它不会在外部设置为另一个有效状态。因此,当先在外部修改my_var,然后再将其设置为默认状态时,就会出现问题。因此,问题是何时初始化my_var。就像上面的标准报价所暗示的那样,还是
volatile
会改变游戏规则?
[首先,让我们看一下标准(C ++ 14 [basic.start.init] 3.6.3 / 4):在实现中定义是否动态初始化具有静态存储持续时间的非局部变量。 ...
如果初始化被推迟到主要声明,它应出现在第一次使用odr(3.2)之前在相同翻译单元中定义的任何函数或变量要初始化的变量。]>
您说“可以从外部来源进行修改”。但是任何此类修改都将是对同一翻译单元中定义的变量(实际上是变量)的odr-use。