Is eliminating construction of unused object allowed in standard even if constructor has observable side-effects?

84 views Asked by At

Consider the following code:

#include <iostream>

struct M {
    M() { std::cout << "M\n"; }
};

template <class T>
struct Test {
    Test() { std::cout << "Test\n"; }
    inline static auto m = M{};
};
int main() {
    Test<int> t1;
    //Test t;
    //(void)&t1.m;
}

Using the latest GCC or Clang the only "Test" is printed out. But if we use an address of m object (uncomment the last line (void)&t1.m;) or transform Test class template into the regular (non-templated) class then the M constructor was called.

Is this behaviour allowed by the C++ standard? Any quotes?

1

There are 1 answers

8
StoryTeller - Unslander Monica On BEST ANSWER

Yes, it's spelled out in the standard.

[temp.inst] (emphasis mine)

4 Unless a member of a class template or a member template is a declared specialization, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist or if the existence of the definition of the member affects the semantics of the program; in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

Since your example doesn't use the static data member at all, its definition is never fully instantiated.