编译后的程序是否可能不包含实例化模板class?

Is it possible that a compiled program does not contain an instantiated template class?

考虑这段代码:

template <typename T>
class A {
    T x;
    // A bunch of functions
};

std::size_t s = sizeof(A<double>);

假设 sizeof 运算符是唯一需要实例化 A<double> 的地方。编译后的程序是否包含A<double>的相关代码(例如A<double>::~A())?

Is it possible that the compiled program does not contain relevant code for A<double> (e.g. A<double>::~A())?

当然可以。

std::size_t s = sizeof(A<double>);

只是一个编译时操作,不需要A<double>的任何运行时实例,因此不需要构造函数、析构函数或其他相关代码 .


即使会有像下面这样的模板函数代码的显式实例化

 if(sizeof(A<double>) <= 4) {
      A<double> a; // Instantiation of constructor and destructor
      a.x = 3.5;
 }

允许编译器优化该代码。

是的,sizeof() 不需要成员函数,因此很可能不会生成它们。所有sizeof需要的都是数据成员。

class会被实例化,但是编译器不能实例化任何成员函数定义,[temp.inst]/1:

[...] the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type[...]

[temp.inst]/2:

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or noexcept-specifiers of the class member functions, [...]

我构建了这段代码:

#include <cstddef>


template <typename T>
class A {
    T x;
    // A bunch of functions
};


int main(const int argc, const char* argv[])
{
    std::size_t s = sizeof(A<double>);
}

然后启动 objdump 我得到这个输出:

$ objdump -t a.out 

a.out:  file format Mach-O 64-bit x86-64

SYMBOL TABLE:
0000000100000000 g     F __TEXT,__text  __mh_execute_header
0000000100000f90 g     F __TEXT,__text  _main
0000000000000000         *UND*  dyld_stub_binder

我们可以看到没有生成与 constructor/destructor 关联的符号。