模板与常规功能的优化:引擎盖下发生了什么?
Optimization of template vs regular function: what's going on under the hood?
从这个问题的答案中,我遇到了一个相当有趣的现象。给定以下两个函数:
void require(void * volatile) { }
template <typename T>
void requireT(T * volatile) { }
使用指向静态数据成员的指针调用每个成员将强制该成员被实例化(这是另一个问题的目的),但是,requireT
将被完全优化,而require
对生成的代码/二进制文件(g++ 4.9.2)产生影响。
这是为什么呢?编译器处理代码的方式有什么区别?
模板是隐式inline
的,但另一个函数不是。
链接器可能假定未使用的inline
函数不需要包含在编译的二进制文件中,因为它的任何客户端代码始终能够在头文件中找到它。(但是,通常,在生成可执行应用程序二进制文件时,所有未使用的函数都会被剥离。
模板代码是在需要的地方生成的,因为事先为可能使用的每个可能类型生成它是不可行的。在那里,当对模板函数的调用被优化时,编译器没有理由自己生成函数。
即使对它们的所有调用都经过优化,也几乎总是生成普通函数,因为它们也可能从不同的编译单元调用。通过将 static 放在前面或将其放在未命名的命名空间中,使函数位于编译单元的本地,可能有助于编译器完全优化函数。
相关文章:
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 这C++代码中发生了什么C++(指数函数)
- 哪种方式更快?究竟发生了什么,我们没有看到什么?
- 我正在将一个 std::string 传递给一个 boost 函数,该函数对该类型进行常量引用,但该值发生了变化
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 从"LLONG_MAX 秒"构造 std::chrono::毫秒变量时发生了什么?
- 这个片段中关于 n 在 pc[i] 中的表示发生了什么
- istringstream,num1 和 num2 在这里发生了什么?
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- libstdc++的make_shared布局在gcc 4.x和gcc 6.x之间是否发生了变化?
- 我是否能够确定在部署一个程序后发生了什么,我在数组末尾写入?
- 为什么我的 int 在 C++ 程序中间发生了变化?
- 这个阶乘程序内部发生了什么?
- C++ - *(int**) 地址?这里发生了什么?
- C++用用户输入在循环中填充 char 数组:输入整个字符串时到底发生了什么?
- 在使用VS2010构建ACE和TAO(CORBA)时发生了许多错误
- 为什么在波纹管程序中发生了从字符串常量到'char*'的警告已弃用的转换
- 让对象知道它创建的 show 函数中发生了什么
- 这里的矢量数组发生了什么?
- 增加顶级常量指针时发生了什么