gpt4 book ai didi

c++ - 非局部非内联变量的初始化 : does it take place strictly before the `main()` function call?

转载 作者:行者123 更新时间:2023-11-30 03:19:03 27 4
gpt4 key购买 nike

在下面的简单程序实现中,数字的打印顺序是自定义的吗?

#include <iostream>


struct Foo
{
Foo()
{
std::cout << "1" << std::endl;
}
};

Foo foo;


int main()
{
std::cout << "2" << std::endl;
}

标准中的一些措辞( Dynamic initialization of non-local variables [basic.start.dynamic]/4):

It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline 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 is initialized in this case, even if it is not itself odr-used ([basic.def.odr], [basic.stc.static]).

the main() function is not odr-used .

最佳答案

允许的输出是 1/2、2 和 2/1。

如果变量 foo 的初始化没有延迟,那么它在 main 开始之前排序,所以 1 打印在 2 之前。

如果延迟初始化,则要求 foo 的初始化必须在任何(其他)odr-use 之前发生foo。它并不是说如果没有 odr-use 就不必进行初始化。对于这个例子,输出 2/1 肯定是非常奇怪的(并且输出 2 是延迟初始化的实现在实践中唯一使用的输出),但我在标准中没有看到任何严格排除它的内容。

我相信标准中的措辞的原因是它允许实现使用一个守卫来延迟翻译单元中所有此类变量的初始化。如果我们像这样修改您的示例:


Foo foo;

struct Bar {
Bar() { std::cout << "3\n"; }
void Use() {}
} bar;


int main()
{
std::cout << "2" << std::endl;
bar.Use();
}

使用单个守卫和延迟初始化,foo 将与 bar 一起初始化,即使 foo 没有 odr-use(除了初始化) 在程序中。在这种情况下,还需要一致性,因为该示例使用 ordered initialization ,因此 foo 的初始化必须在 bar 之前进行排序,因此唯一允许的输出是 1/3/2(无延迟初始化)和 2/1/3(延迟初始化)。但是如果我们使用不同的构造来获得无序初始化,一个实现也可能产生 2/3/1(同样,没有非初始化 ODR-使用 foo) .

关于c++ - 非局部非内联变量的初始化 : does it take place strictly before the `main()` function call?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54167232/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com