gpt4 book ai didi

C++ 为什么在定义的编译和链接之前引用外部实例的程序

转载 作者:行者123 更新时间:2023-12-02 11:20:45 25 4
gpt4 key购买 nike

这个问题可以用一个简单的例子来说明:

extern A<bool> a;
B b(a);
A<bool> a("a");

在头文件中:

template<typename T>
class A {
public:
A(const char * name) : m_name(name) {}

const char * name() const {
return m_name;
}
...
...
private:
const char * m_name;
};

class B {
public:
B(A<bool> & a) {
printf("%s = %p\n", a.name(), &a);
}
};

代码实际上编译、链接并生成:

(null) = 0044F604

Demo

我想知道这是否不应该被编译器捕获并失败。

有问题的编译器是gcc 9.2.0 (mingw-w64-i686)

最佳答案

在 C++ 中,同一翻译单元内的全局对象按照定义的顺序进行初始化(尽管 TU 之间的顺序是 undefined )。请参阅[basic.start.init]/2 :

... Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit.

另一方面,静态存储持续时间的对象的存储空间是在程序加载时分配的,因此每个全局对象从一开始就有一个地址。

一般来说,在 C++ 中,允许引用尚未初始化的对象,但访问它是未定义的行为。一般来说,未定义的行为不需要诊断。

在您的情况下,B 可以通过对 A 的引用来构造,并且它可以保存传入的引用以供以后使用:

class B {
A<bool> & a_;
public:
B(A<bool> & a) : a_(a) { }

void run() {
printf("%s = %p\n", a_.name(), &a_);
}
};

关于C++ 为什么在定义的编译和链接之前引用外部实例的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59157077/

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