Clang/LLVM 7 and 8 on Windows initialize inline static data member multiple times (with both link.exe and lld-link.exe)

The primary feature of the inline keyword is that it amends the ODR rule in two ways:

  1. Multiple definitions (with some restrictions) are allowed

  2. The resulting objects are "folded" into a single instance:

    An inline function or variable with external linkage shall have the same address in all translation units.

The only addition in C++17 is that it also allows a static data member declaration to be a definition. That's it.

A static data member still has the same linkage (external in your case), storage duration and lifetime, and for all practical purposes works just like a globally defined variable. See [class.static.data]/6:

Static data members are initialized and destroyed exactly like non-local variables

That means essentially that it should work the same as this:

struct A
{
  A()      { std::cout << "ctor "; }
  ~A()     { std::cout << "dtor "; }
};

A a; // in one of the TU's

extern A a; // in all other TU's

Conclusion:

It's a bug in Clang. The static S::a must be initialized and destroyed once.