请问需要翻译成哪种语言呢?
代码使用 gcc (-std=c++11) 编译和运行良好,输出如下:
现在,参考cppreference.com:
就我所看到的,
因此,我的问题是: 是否由于gcc的实现定义行为而导致
struct A
{
void Register(const char* s);
const char* m_s[10];
int m_i = 0;
};
A& GetA();
a.cpp
:
#include "a.h"
#include <stdio.h>
void A::Register(const char* s)
{
m_s[m_i++] = s;
}
A& GetA()
{
static A instance;
return instance;
}
int main(int argc, char* argv[])
{
A& a = GetA();
int n = a.m_i;
for (int i = 0; i < n ; ++i)
printf("%s\n", a.m_s[i]);
return 0;
}
b.cpp
:
#include "a.h"
struct B
{
B() { GetA().Register("b"); }
static B* instance;
};
B* B::instance = new B;
c.cpp
:
#include "a.h"
struct C
{
C() { GetA().Register("c"); }
static C* instance;
};
C* C::instance = new C;
代码使用 gcc (-std=c++11) 编译和运行良好,输出如下:
c
b
现在,参考cppreference.com:
请注意,延迟动态初始化
对于动态初始化是否在主函数的第一个语句(静态成员)或线程的初始函数(线程本地)之前发生是由实现定义的,还是推迟发生。
如果非内联变量的初始化被推迟到main/thread函数的第一个语句之后才发生,那么它会在与要初始化的变量在同一翻译单元中定义的任何具有静态/线程存储期的变量的第一个odr-use之前发生。如果从给定的翻译单元中没有使用odr-used变量或函数,则该翻译单元中定义的非本地变量可能永远不会被初始化(这模拟了按需动态库的行为)。然而,只要来自TU的任何内容都被odr-used,所有具有副作用的初始化或销毁的非本地变量都将被初始化,即使它们没有在程序中使用。
a.cpp
不知道B
和C
的存在,而B
和C
与A
的唯一交互是其各自实例的构造期间对GetA()
和A::Register()
的调用。就我所看到的,
B
和C
实例都不是ODR-used,当然也不是从main()
的翻译单元中使用。它们的初始化显然具有副作用,但在main()
进入之前或在main()
打印注册字符串之前,甚至根本没有保证此初始化将发生。因此,我的问题是: 是否由于gcc的实现定义行为而导致
B
和C
实例在main()
打印已注册字符串之前进行初始化?
如果是由标准保证的,那么是如何保证的?
__attribute__((init_priority(x)))
。 - Passer ByB::instance
在main开始执行之前为nullptr。 - StoryTeller - Unslander Monica