Clang/LLVM 7 and 8 on Windows initialize an inline static data member once per TU. As far as I understand C++17 this is not correct.
Although an inline variable may be defined in multiple TUs the compiler and/or linker must ensure that it exists only once in a program and hence is initialized exactly once.
The following little program shows what happens with Clang/LLVM (tested in Visual Studio 2017 and 2019 RC with LLVM Compiler Toolchain extension):
// header.h
#include <iostream>
struct A
{
A() { std::cout << "ctor " << this << std::endl; }
~A() { std::cout << "dtor " << this << std::endl; }
void f() { std::cout << "f " << this << std::endl; }
};
struct S
{
inline static A a; // C++17 inline variable, thus also a definition
};
// TU1.cpp
#include "header.h"
int main()
{
S::a.f();
}
// TU2.cpp
#include "header.h"
// TU3.cpp
#include "header.h"
// TU4.cpp
#include "header.h"
This program prints:
ctor 010D4020
ctor 010D4020
ctor 010D4020
ctor 010D4020
f 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
dtor 010D4020
That's four initializations for the one and only object of A (in fact one per TU) instead of exactly one (as C++17 demands).
The program should print:
ctor 010D4020
f 010D4020
dtor 010D4020
This is what MSVC does, by the way.
This is a bug in clang/LLVM, right?