有时我喜欢将初始化代码放在静态对象的构造函数中,就像这样。
namespace
{
struct Init {
Init ();
};
Init :: Init () {
// whatever
}
Init init;
}
是的,我知道这通常很糟糕,因为您不能依赖翻译单元之间的初始化顺序,但有时,对于某些事情来说,这是可以的。
无论如何,我不喜欢这种语法,今天我尝试了这个。
namespace
{
int init = [] () -> int {
// whatever
return 0;
} ();
}
当程序运行时,whatever
代码在之后main()
运行!
我知道像这样的静态初始化以任意顺序发生,但我认为规范要求它全部以任何顺序发生之前 main( )
输入。
编译器是否行为不当或者是否存在进一步的微妙之处?
#> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.8/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.1-10ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)
最佳答案
在标准中找到了这一点(3.6.2 非局部变量的初始化 [basic.start.init], 4):
It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable defined in the same translation unit as the variable to be initialized.*
* A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not odr-used (3.2, 3.7.1).)
似乎明确表示,至少在某些情况下,初始化可以推迟到 main 进入之后。
关于c++ - 当我的程序退出时静态数据被初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21482880/