从this question的回答中我发现了一个相当有趣的现象。鉴于以下两个功能:
void require(void * volatile) { }
template <typename T>
void requireT(T * volatile) { }
使用指向静态数据成员的指针调用每个成员将强制实例化该成员(这是另一个问题的目的),但requireT
将完全优化,而require
对结果代码/二进制文件有影响(g ++ 4.9.2)。
这是为什么?编译器如何处理代码有什么区别?
答案 0 :(得分:0)
模板代码是在需要的地方生成的,因为对于可能使用的每种可能类型,都不可能事先生成模板。当对模板函数的调用被优化掉时,编译器没有理由自己生成函数。
即使所有对它们的调用都被优化掉,也几乎总是生成普通函数,因为它们也可能从不同的编译单元调用。通过在将静态放入未命名的命名空间之前将函数设置为编译单元的本地函数可能有助于编译器完全优化该函数。
答案 1 :(得分:0)
模板隐式inline
,但另一个功能不是。
链接器可能会假定未使用的inline
函数不需要包含在已编译的二进制文件中,因为任何客户端代码都始终能够在头文件中找到它。 (但通常,在生成可执行应用程序二进制文件时,将删除所有未使用的函数。)