Issue
So I am updating some C++11 code to use gcc-11, and have run into a issue...
Namely, it appears that in gcc-11 the constructor symbol, for a class, which is explicitly instantiated, does not exist if the constructor uses a type from a template class, defined in an anonymous namespace.
A simplified example that produces the issue can be seen below.
Clang-12 and gcc-8 do not exhibit this behavior and export the symbols (as I would have expected).
template.h:
#pragma once
namespace {
template <typename T>
struct MyAnonTempStruct
{
typedef float BaseType;
};
}
template <typename T>
class MyTemplateClass
{
public:
typedef typename MyAnonTempStruct<T>::BaseType BaseType;
public:
MyTemplateClass(const BaseType* array);
};
template.cpp:
#include "template.h"
template <typename T>
MyTemplateClass<T>::MyTemplateClass(const BaseType* array)
{
}
template class MyTemplateClass<float>;
Using the compilation command
gcc -c -o template.o template.cpp
using nm I get the following symbol output for Clang-12 and gcc-8:
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 n MyTemplateClass<float>::MyTemplateClass(float const*)
For gcc-11 I only get a text symbol:
0000000000000000 t MyTemplateClass<float>::MyTemplateClass(float const*)
If I mark the explicit specialization as extern in the header things work again in gcc-11. ie, adding:
extern template class MyTemplateClass<float>;
So I guess my question is: Is this expected behavior, and the fact that it previously worked was just because it was undefined, or is this some form of a miscompilation?
Solution
Anonymous namespaces generally should not be used in header files. There are very few exceptions to this, and your use case is not one. You can use a namespace detail
to suggest to people that the code inside is not meant for them to use.
GCC 11 is doing nothing wrong here, your code is simply not portable.
Answered By - John Zwinck Answer Checked By - Candace Johnson (WPSolving Volunteer)