Linking error with g++ for static inline thread_local variable

139 Views Asked by At

I have three files I am compiling together using CMake (smallest example that produces the error):

lib.h

#ifndef lib
#define lib

struct StructOuter{
    struct StructInner{
        int a;
        StructInner(int aa) {
            a = aa;
        }
    };

    static inline thread_local StructInner problemStruct{3};
};


#endif

other.cpp

#include "lib.h"

main.cpp

#include "lib.h"

int main() {
    StructOuter t = StructOuter{};
    return t.problemStruct.a;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)
project(proj)

set(CMAKE_CXX_STANDARD 20)

add_executable(proj main.cpp other.cpp)

Here I get the error:

multiple definition of `TLS init function for StructOuter::problemStruct' ... collect2.exe: error: ld returned 1 exit status ninja: build stopped: subcommand failed

I get the error on my Windows computer where I am using Clion with g++ from MinGW with gcc 9.3 and compiling with C++20. More info:

  1. With my understanding of static inline, it should exactly avoid that there are multiple definitions across different translation units like here.

  2. Since the lib.h file is in the header-only library I do not want to change anything in there, I believe the error is somehow in my build setup.

  3. The issue is gone when I remove the keyword 'thread_local'.

  4. Changing to clang64 compiler on my Windows also fixes the problem, and the project compiles with no errors!

My best bet is that this is a bug in the g++ compiler (or linker) from MinGW (maybe same issue as mentioned here: sourceware?). Any help in understanding what is going on is much appreciated.

0

There are 0 best solutions below