mardi 2 février 2016

std::string & as template parameter and abi_tag in gcc 5

Consider the following piece of code (test1.cpp):

#include <string>

extern std::string test_string;

template<std::string &s>
class test{
public:
   static void bar(){ }
};

std::string test_string("test string");
void foo(){test<test_string>::bar();}

Now let us switch order of two last lines of code (test2.cpp):

#include <string>

extern std::string test_string;

template<std::string &s>
class test{
public:
   static void bar(){ }
};

void foo(){test<test_string>::bar();}
std::string test_string("test string");

Nothing should change. But if you look via objdump to compiled file you will see difference:

objdump -t -C test*.o | grep bar

In one case template test was instantiated as:

test<test_string[abi:cxx11]>::bar()

and in another as:

test<test_string>::bar()

both files are compiled just with

gcc -c test*.cpp

So reference to std::string as template parameter is treated as not tagged if it is just declared extern. And it is treated as tagged after definition.

Some classes in my project are instantiated twice where there should be just one class. It is rather unpleasant.

gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2)

Is it a bug in compiler? Or is it expected behavior? What can be a workaround?

Aucun commentaire:

Enregistrer un commentaire