模板与常规功能的优化:引擎盖下发生了什么?

Optimization of template vs regular function: what's going on under the hood?

本文关键字:引擎 发生了 什么 优化 常规 功能      更新时间:2023-10-16

从这个问题的答案中,我遇到了一个相当有趣的现象。给定以下两个函数:

void require(void * volatile) { }
template <typename T>
void requireT(T * volatile) { }

使用指向静态数据成员的指针调用每个成员将强制该成员被实例化(这是另一个问题的目的),但是,requireT将被完全优化,而require对生成的代码/二进制文件(g++ 4.9.2)产生影响。

这是为什么呢?编译器处理代码的方式有什么区别?

模板是隐式inline的,但另一个函数不是。

链接器可能假定未使用的inline函数不需要包含在编译的二进制文件中,因为它的任何客户端代码始终能够在头文件中找到它。(但是,通常,在生成可执行应用程序二进制文件时,所有未使用的函数都会被剥离。

模板代码是在需要的地方生成的,因为事先为可能使用的每个可能类型生成它是不可行的。在那里,当对模板函数的调用被优化时,编译器没有理由自己生成函数。

即使对它们的所有调用都经过优化,也几乎总是生成普通函数,因为它们也可能从不同的编译单元调用。通过将 static 放在前面或将其放在未命名的命名空间中,使函数位于编译单元的本地,可能有助于编译器完全优化函数。