0

-Edit- the 'dupe' has nothing to do with the linker which is the problem here

I compiled the code below with g++ main.cpp test.cpp

If I use test.cpp (so the source is inlined) instead of test.h it'll work fine, but in my real case I need a different file. The linker complains with the below. How do I write this so the linker is happy?

/usr/bin/ld: /tmp/ccgBHBw2.o: in function `TLS wrapper function for Test<4, 8>::v':
main.cpp:(.text._ZTWN4TestILi4ELi8EE1vE[_ZTWN4TestILi4ELi8EE1vE]+0x15): undefined reference to `Test<4, 8>::v'
collect2: error: ld returned 1 exit status

main.cpp

#include<cstdio>
#include<cstdlib>
#include<cstring>

#include "test.h"
//*/#include "test.cpp"

int main(int argc, char *argv[])
{
    Test<4, 8> t;
    t.test(4, 8);
    return 0;
}

test.h

#include<cassert>

template<int A, int B>
struct Test {
    static thread_local int v;
    static int test(int a, int b) {
        assert(A == a);
        assert(B == b);
        return v;
    }
};

test.cpp

#include "test.h"
template<int A, int B>
thread_local int Test<A, B>::v;
Spill
  • 45
  • 5
  • @273K that dupe has nothing to do with this – Spill Jul 26 '23 at 01:46
  • Compiles for me if I move the relevant part of test.cpp into test.h. Why don't you think the dupe applies? – Stephen Newell Jul 26 '23 at 01:50
  • @StephenNewell the dupe talks about needing the body so the compiler can produce the function, here the problem is not being able to find data (the tls var) – Spill Jul 26 '23 at 01:53
  • `undefined reference to \`Test<4, 8>::v'` this definition is not available in TLS. – 273K Jul 26 '23 at 02:00
  • @273K Are you saying it's impossible to implement this in a way that allows multiple files can access the same TLS data? Feels weird it isn't an outright compile error when I write thread_local. Either way the 'dupe' has nothing about tls – Spill Jul 26 '23 at 02:03
  • It's allowed, see the Alternative solution of the first answer. I doubt you want instantiate all such `int Test<4, 8>::v;`, thus you have to bring it to the .h file or make it static inline. – 273K Jul 26 '23 at 02:05
  • 1
    @273K is that a weird way of saying write the var as `static thread_local inline int v;`? It looks like that works. Although the page this question redirects to isn't saying that at all – Spill Jul 26 '23 at 02:24
  • It might seem strange because `inline` doesn't do inlining. It only says something about there being only one definition. – Pepijn Kramer Jul 26 '23 at 03:11

0 Answers0