非本地非内联变量的初始化:是否严格在"main()"函数调用之前进行
The initialization of non-local non-inline variables: does it take place strictly before the `main()` function call?
是否定义了以下简单程序实现中打印数字的顺序?
#include <iostream>
struct Foo
{
Foo()
{
std::cout << "1" << std::endl;
}
};
Foo foo;
int main()
{
std::cout << "2" << std::endl;
}
标准中的一些词语(非局部变量的动态初始化[basic.start.Dynamic]/4):
实现定义了具有静态存储持续时间的非本地非内联变量的动态初始化是在
main
的第一条语句之前排序还是推迟。如果它被推迟,它强烈发生在任何非初始化或使用任何非内联函数或在与要初始化的变量相同的转换单元中定义的非内联变量之前。**)在这种情况下,具有静态存储持续时间的非局部变量被初始化,该变量的初始化具有副作用,即使它本身没有使用odr([basic.def.odr],[basic.stc.static])
并且未使用main()
函数。
允许的输出为1/2、2和2/1。
如果变量foo
的初始化是而不是延迟的,则它在main
开始之前被排序,因此1
在2
之前被打印。
如果推迟初始化,则要求foo
的初始化必须在任何(其他)odr使用foo
之前进行。它并没有说,如果没有odr的使用,就不必进行初始化。对于这个例子来说,输出2/1肯定是非常奇怪的(输出2是延迟初始化的实现在实践中唯一使用的),但我在标准中没有看到任何严格排除它的东西。
我相信标准中措辞的原因是,它允许实现使用一个保护来推迟翻译单元中所有此类变量的初始化。如果我们这样修改您的示例:
…
Foo foo;
struct Bar {
Bar() { std::cout << "3n"; }
void Use() {}
} bar;
int main()
{
std::cout << "2" << std::endl;
bar.Use();
}
通过单个保护和延迟初始化,foo
将与bar
一起初始化,即使程序中没有对foo
的odr使用(除了初始化)。在这种情况下,它也是一致性所必需的,因为该示例使用有序初始化,因此foo
的初始化必须在bar
之前排序,因此唯一允许的输出是1/3/2(无延迟初始化)和2/1/3(延迟初始化)。但是,如果我们使用不同的构造来获得无序初始化,那么一个实现也可能产生2/3/1
(同样,没有使用foo
的非初始化)。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 代码在main()中运行,但在函数中出现错误
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 函数是否可以访问传递给main()的参数
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 我的 int main() 中出现堆栈溢出错误
- C++变量名(可以将 main 声明为变量,但对于其他函数名称则不然)
- 当我尝试在 Main 中调用插入函数时,它不是取数字?
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 为什么类和 main() 函数中也有动态内存分配
- 在 main.cpp 的上下文中找不到目录(带有 CMake 的快板)
- 我想在 Main 中用 C++ 调用其他类中的一个类,但我做不到
- "main"函数堆栈中的对象在第一个任务运行时被覆盖 (FreeRTOS)
- 为什么 'main' 函数中的局部 int 变量会自动初始化?
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- 为什么在我的 main 函数中声明整数后我的整数数组中会出现错误?
- 为什么要从main()返回NULL?
- main() 中的 std::cout 在调试期间不会在调试控制台中打印任何内容