1

If I explicitly instantiate a template class which has a default destructor, default move constructor, etc, and never use that type in that translation unit, then it does not include the compiler-generated member functions.

For instance, if a template class array2d has compiler generated member functions e.g.:

  array2d(array2d const &b) = default;
  array2d(array2d &&b) noexcept = default;
  ~array2d() = default;
  array2d &operator=(array2d const &) = default;
  array2d &operator=(array2d &&) noexcept = default;

and if I explicitly instantiate this like so:

#include "array2d.hh"
template class array2d<float>;

and compile this to array.cc.o I get these symbols:

0000000000000000 W void swap<float>(array2d<float>&, array2d<float>&)
0000000000000000 W array2d<float>::swap(array2d<float>&)
0000000000000000 W array2d<float>::array2d(long, long)
0000000000000000 W array2d<float>::array2d()
0000000000000000 W array2d<float>::array2d(long, long)
0000000000000000 W array2d<float>::array2d()
0000000000000000 n array2d<float>::array2d(long, long)
0000000000000000 n array2d<float>::array2d()
0000000000000000 W array2d<float>::operator()(long, long)
0000000000000000 W array2d<float>::operator[](long)
0000000000000000 W array2d<float>::rows() const
0000000000000000 W array2d<float>::empty() const
0000000000000000 W array2d<float>::columns() const
0000000000000000 W array2d<float>::operator()(long, long) const
0000000000000000 W array2d<float>::operator[](long) const

None of the symbols for compiler generated member functions exist.

Why doesn't explicit template class instantiation create these symbols?

Levi Morrison
  • 19,116
  • 7
  • 65
  • 85
  • The tool chain(s) used to produce this would be a welcome addition to your question. And was that symbol dump from your final *executable* , or just the object module before actual use? – WhozCraig Jul 23 '18 at 06:55
  • This is just the object module before use. I tested 3 toolchains: GCC 5.4 and 7.2, and Clang 3.8, which are the compilers I had at hand. All toolchains acted the same in that they don't create these symbols in the object file. The difference, and the reason I discovered this, is that only some compilers will add them in the other translation units, and others will not. Those that do not add them will then error, because the symbol doesn't exist anywhere. – Levi Morrison Jul 23 '18 at 07:03
  • Try to have just declarations in the header file (such as `array2d(array2d const &b);` and then add corresponding definitions in your source (`template array2d::array2d(array2d const & b) = default;`) where explicit instantiation takes place. In your case, a compiler sees the defaulted definitions in every compilation unit, so it does not have to generate the assembly code in the unit where explicit instantiation happens. Instead, it can generate the code in the unit where these functions are called (and apply inlining etc.). – Daniel Langr Jul 23 '18 at 07:03
  • @DanielLangr Doing that causes them to be defined in the object file, but that technique isn't widely applicable (e.g. to code that comes from another project). It also doesn't explain why the compiler doesn't generate the symbols in the first place for the compiler generated member functions. – Levi Morrison Jul 23 '18 at 07:19
  • @LeviMorrison If the template definition is in the header file, why do you need explicit instantiation? I believe the purpose of explicit instantiation is that you put only template declarations (template class member function declarations) in the header file and their definitions in the source file together with explicit instantiations. But in your case, you have special member functions _definitions_ in your header file. So, again, its visible across all compilation units. – Daniel Langr Jul 23 '18 at 07:23
  • @LeviMorrison But I agree that compilers behave a bit inconsistently here. For instance in this case: https://godbolt.org/g/U4CUnH, both Clang and GCC generate object code for the default constructor and the ordinary member function in the object file, while both are defined within class body. – Daniel Langr Jul 23 '18 at 07:30

0 Answers0