The problem can be shown on a simple example:
extern A<bool> a;
B b(a);
A<bool> a("a");
In header file:
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);
}
};
The code actually compiles, links and produce:
(null) = 0044F604
I wonder if this shouldn't be caught by compiler and fail.
Compiler in question is gcc 9.2.0 (mingw-w64-i686)
.
See basic.life/6 and basic.life/7 for detailed information.
In C++, global objects within the same translation unit are initialized in the order they are defined (though the order across TU's is undefined ). See [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.
On the other hand, storage for objects of static storage duration is allocated at program loading time, so each global object has an address from the beginning.
In general in C++ it is allowed to reference a not-yet-initialized object, but accessing it is undefined behavior. Generally no diagnostic is required for undefined behavior.
In your case, B
can be constructed with a reference to A
, and it can save the passed-in reference to be used later:
class B {
A<bool> & a_;
public:
B(A<bool> & a) : a_(a) { }
void run() {
printf("%s = %p\n", a_.name(), &a_);
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.