简体   繁体   中英

C++ Why program with extern instance referenced before defined compiles and links

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

Demo

I wonder if this shouldn't be caught by compiler and fail.

Compiler in question is gcc 9.2.0 (mingw-w64-i686) .

  1. There is nothing wrong with passing around and using references to uninitialised objects. The standard explicitly allows this.
  2. It is the programmer's responsibility to use such a reference in one of the limited ways permitted by the standard. The compiler is not required to complain if usage falls outside of the permitted range. Instead, the behaviour of a program that does this is undefined.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM