0

From here:

Great answer. Additionally most modern linkers will remove redundant code like template instantiations.

  • What does redundant template instantiations here mean?
  • Aside of template instantiations, what else codes will be redundant when link-time?

I will try to answer the first question on my own, if anywhere is wrong, please correct me. BTW, please forgive my poor English :-)

Chen Li
  • 4,824
  • 3
  • 28
  • 55

1 Answers1

-1
  • What does redundant template instantiations here mean?

Assume we have a template <typename T> class A {}; which is declared in the a.hpp. We have two ways to instantiate an object in the a.cpp:

1. explicit instantiation

  • Explicit instantiation definition: template class A <type>;
  • Explicit instantiation declaration: extern template class A <type>;

2. implicit instantiation

  • When code refers to a template in context that requires a completely defined type, or when the completeness of the type affects the code, and this particular type has not been explicitly instantiated, implicit instantiation occurs

When the TUs cannot find the explicit instantiation definition or declaration, tA<int> a; will invoke implicit instantiation.

difference between specialization and instantiate


Let's return the Question: What does redundant template instantiations here mean?

I will divide it into several cases within one a.cpp:

Case 1 ---- implicit instantiation

#include "a.h"
A<int> a;

=>

class A<int>
{

};

A<int> a;

Case 2 ---- implicit instantiation

#include "a..h"
A<int> a;
A<int> b;

=>

class A<int> 
{

};

A<int> a;
A<int> b;

Case 3 ---- Explicit instantiation definition:

#include "a.h"
template class A<int>;
A<int> a;

=>

#include "a.h"
template class A<int>;
A<int> a;

Conclusion:

  • Implicit instantiation will produce redundant template instantiations while explicit instantiation definition/declaration won't.
  • Linker will remove such redundant template instantiations, but it will increase link-time.

If you wonder how does the linker work to remove redundant template instantiations, please read this thread: How does the linker handle identical template instantiations across translation units?

Chen Li
  • 4,824
  • 3
  • 28
  • 55
  • 1
    No, you cannot explicitly instantiate the same template specialization in multiple translation units. [temp.spec]/5: "For a given template and a given set of _template-arguments_, an explicit instantiation definition shall appear at most once in a program." – aschepler Jun 11 '18 at 11:53
  • There are more issues with this answer. For instance, it presumes that header files are not part of translation units (most clearly seen in point 2, where there's a bold **or**). This erroneous assumption leads to multiple logical problems further on, such as misinterpreting the One Definition Rule. – MSalters Jun 11 '18 at 12:21
  • @aschepler http://eel.is/c++draft/temp.spec#5 (5.1): **an explicit instantiation definition** shall appear at most once in a program, (5.2): an **explicit specialization** shall be defined at most once in a program, as specified in **[basic.def.odr]**, and I think the wording here is different, *5.1* doesn't emphasize **odr**, *5.2* emphasizes. – Chen Li Jun 11 '18 at 12:30
  • @aschepler Besides, http://eel.is/c++draft/basic.def.odr#12 *There can be more than one definition of ......class template,......in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.* – Chen Li Jun 11 '18 at 12:33
  • @MSalters Thanks for your correction! I will replace translation unit with source file. More corrections are welcome :-) – Chen Li Jun 11 '18 at 12:36
  • @MSalters several places about *translation units* fixed – Chen Li Jun 11 '18 at 12:44
  • 1
    I also think you're confusing template definitions `template class Foo { };` and explicit instantiation definitions `template class Foo`. The ODR specifically applies to the former, so template definitions. – MSalters Jun 11 '18 at 12:50
  • @MSalters Thanks again! It's my fault. Now it is fixed :) – Chen Li Jun 11 '18 at 12:58
  • 1
    @陳力 [temp.spec]/5.1 is an additional requirement similar to but written as independent of the ODR. And what would 5.1 mean, if not that you can't explicitly instantiate the same thing twice, even in different TUs? The template part of the quote is talking about implicit instantiations: multiple TUs may implicitly instantiate a template specialization, or one TU may explicitly instantiate and other TUs may implicitly instantiate. – aschepler Jun 11 '18 at 13:00
  • @aschepler Sorry, sir. It's my fault. Now it is fixed – Chen Li Jun 11 '18 at 13:00
  • 1
    I'm still a bit unhappy with the text as written. There's no special treatment for header files versus source files. That's mixing up the phases of translation. Merging a source file and its header files into a Translation Unit has completed before template compilation starts. Furthermore, implicit instantiation is only suppressed if the explicit instantiation (declaration or definition) precedes the implicit instantiation. These details matter; while it's convention to `#include` header files before anything else it's not mandatory. – MSalters Jun 11 '18 at 14:15
  • @MSalters Quite agree with you. I also think details are vitally important. The only happy thing today is the **really, really valuable** corrections made by you and aschepler. I'll re-organize the answer tomorrow(11:35 PM now, and I have to go to power/water plant for production practice tomorrow morning) – Chen Li Jun 11 '18 at 15:42
  • @MSalters [practice is over](https://twitter.com/_FirstLoveLife_/status/1006464694230454272). If I understand correctly, I think you suggest me to replace head file/source with TU? I made a few editions. But I think you will still be unsatisfied with the answer. If you are willing to edit my answer(directly or community wiki), I will feel honored(Indeed, this is a bad answer, but I am still unwilling to delete it, because your comments are valuable to me) – Chen Li Jun 12 '18 at 09:55