PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, June 26, 2022

[FIXED] Why does 'extern template class' technique not work as expected?

 June 26, 2022     c++, c++11, compiler-errors, performance, templates     No comments   

Issue

The original question has been refined.

Given a source code file named main.cpp as follows:

#include <string>
extern template class std::basic_string<char>;

template<typename T>
struct A
{
    T n = {};

    T get() const
    {
        return n;
    }
};

extern template struct A<int>;

int main()
{
    auto a = A<int>{}.get(); // undefined reference to `A<int>::get() const'
    auto b = static_cast<int>(std::string{}.size()); // ok

    return a + b;
}

What I expected:

Note that the source code has extern template class std::basic_string<char> but no template class std::basic_string<char>.

So, the compiler would not instantiate class std::basic_string<char>, then g++ main.cpp would cause link errors on line std::string{}.size() as on line A<int>{}.get().

What I observed:

It is ok to g++ main.cpp on line std::string{}.size(). Online demo

Why does extern template class technique not work as expected?


Solution

There are at least two reasons why it doesn't work.

One There is no prohibition against library class and function template instantiations being declared as extern template by the implementation. gcc and libstdc++ do just that.

$ g++ -E main.cpp | grep 'extern.*string'
extern template class basic_string<char>;      // <-- from the library
extern template class basic_string<wchar_t>;   // <-- from the library
extern template class std::basic_string<char>; // <-- your line

The standard library implementation contains the explicit instantiation definitions (you can dig the source).

Two An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required [temp.explicit].

A possible rationale for the NDR is that extern template should not prevent inlining and other uses that do not involve linking. Indeed, with -O2 A::get is inlined, and the program builds just fine. There is no established technology that would force this program to be rejected no matter what. It can be rejected because of linker errors, but there is no requirement for linker errors to appear.



Answered By - n. 1.8e9-where's-my-share m.
Answer Checked By - Katrina (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing