Explicit instantiation of GCC 6.1 gives undefined character for default constructor

Put this in a file called t.hpp:

#include <unordered_map>

extern template class std::unordered_map<int, int>;

std::unordered_map<int, int> getMap();

And this is in t.cpp:

#include "t.hpp"

std::unordered_map<int, int> getMap()
{
    return std::unordered_map<int, int>();
}

template class std::unordered_map<int, int>;

Then create it (on Linux):

g++ -std=c++11 -shared -fPIC -o t.so t.cpp

Then look at the constructors in the shared object:

objdump --syms --demangle t.so | grep '::unordered_map()'

If you compiled GCC 4.9, it should not show anything. With GCC 5.1 or 5.3, it should show something like this:

8a w F .text 1b std::unordered_map<int, int>::unordered_map()

But with GCC 6.1, it shows something like this:

0 *UND* 0 std::unordered_map<int, int>::unordered_map()

This means that the default constructor for the map does not stand out in the shared object, although it should be. This causes links to fail later when using the shared object in the executable.

If you compile with -O1or above, the problem disappears (the constructor is built-in).

, t.cpp t.hpp. , , - #define SOMETHING t.cpp #include "t.hpp", #ifndef SOMETHING t.hpp. GCC 6, , .

​​GCC 6.1? ?

: : https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57728, , ​​ GCC 4.8, " t 6.1. GCC 5.1 vs 4.9 = default , , GCC 6.1 .

+4

Source: https://habr.com/ru/post/1656546/


All Articles