1

I am having a hard time understanding why the following won't link. The error (GCC 8.3) is

ld: In function `Foo<&(void bar<double>())>::doThing()':
main.cpp: undefined reference to `void bar<double>()'

The code in question:

main.cpp:

#include "base.hpp"

// Links and runs fine if explicitly instantiated:
// Foo<bar<double>> fbd;

int main(int, char**) {
    Base<int> d;

    return 0;
}

base.hpp:

#pragma once

#include "foo.hpp"
#include "bar.hpp"

// Links fine if Base is not a template
template<typename T>
class Base {
public:
    Base() {
        Foo<bar<double>> fbd1;
        Foo<bar2> fbd2;

        fbd1.doThing(); // If doThing is not virtual and not called it links fine
        fbd2.doThing();
    }
};

foo.hpp:

#pragma once

template<void (*callMe)()>
class Foo {
public:
    // If doThing is not virtual, it links fine
    virtual void doThing() {
        callMe();
    }
};

bar.hpp:

#pragma once

#include <iostream>

// If bar is not a template, it links fine
template<typename T>
inline void bar() {
    std::cout << "hello1" << std::endl;
}

inline void bar2() {
    std::cout << "hello2" << std::endl;
}

I am obviously missing something, because to me it looks like the compiler should be able to see and produce the required template specializations. Any suggestions on how to fix this, and pointers on why the changes marked with comments resolve the linker problems, would be appreciated.

Update:

This seems to compile fine on clang 7.1.0.

laobeylu
  • 283
  • 3
  • 14
  • Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Feb 01 '20 at 03:26
  • I'm curious to see how other compilers deal with this. Almost the same result with gcc 9.2: I still get a link error when `doThing` is not virtual. So, basically, it boils down to: if a template parameter that's a function pointer is a template function pointer, does that count as instantiating the template function? – Sam Varshavchik Feb 01 '20 at 03:32
  • I just tested thins on clang and it compiles and runs fine. I will check @KenWhite's comment and see if it helps. – laobeylu Feb 01 '20 at 03:34
  • No, that other question is unrelated here. All template definitions are in a single translation unit, all the templates are fully defined. I can't think of any reason this is not a gcc bug. – Sam Varshavchik Feb 01 '20 at 03:36
  • Looks like it might be a bug in gcc, since clang handles it fine and everything being in the same translation unit was exactly why I was finding this confusing. – laobeylu Feb 01 '20 at 03:39

0 Answers0