在 Compiler Explorer 上比较函数和函数模板之间的输出
Comparing the outputs between a function and a function template on Compiler Explorer
我实现了阶乘函数的简单版本,两者都可以看到 here。我正在使用 GCC T运行k。有 2 个源文件,第一个是函数版本,第二个是模板版本。每个源文件都有 2 个带有关联输出的附加编译器。每个源文件的两个附加编译器之间的唯一区别是左侧编译器没有打开编译器标志或优化,而右侧版本 -O3
设置为打开 3 级优化。
这是我的功能:
// Function Version
int factorial(int n) {
if (n == 0 || n == 1) return 1;
if (n == 2) return 2;
return (n * factorial(n-1));
}
// Template Version:
template<unsigned N>
static auto constexpr factorial_t() {
return (N * factorial<N-1>());
}
template<>
auto constexpr factorial_t<0>() {
return 1;
}
template<>
auto constexpr factorial_t<1>() {
return 1;
}
template<>
auto constexpr factorial_t<2>() {
return 2;
}
现在,当我使用 c++17
在本地 PC 上 运行 安装 IDE
Visual Studio 2017
时,我得到了预期的输出 return从 main()
返回,并且 returned 值对于两种实现都是正确的。
我将其移植到 Compiler Explorer 以测试其他编译器及其优化,以比较它们生成的汇编指令。这是一个相当简单的过程。
现在当我 运行 这些功能时:
来源#1
int main() {
return factorial(6);
}
来源#2
int main() {
return factorial_t<6>();
}
编译器资源管理器生成以下指令计数...
-
| Assembly Instruction Count |
-
Type | Without O3 | With O3 Turned On |
-
Function | 34 | 29 |
-
Template | 50 | 3 |
一切都很好。
所有四个程序执行return一个值208
。
现在回答我的问题:
然而,在第一个和第三个编译器的汇编中,如果不做一些寄存器数学运算,这并不明显,但是在第二个也是最后一个,-O3
为 function
和 template
版本,值 720
在 main()
的 return 调用之前被存储到 EAX
寄存器中。为什么编译器资源管理器显示:Program returned: 208
而不是 720
?
我实现了阶乘函数的简单版本,两者都可以看到 here。我正在使用 GCC T运行k。有 2 个源文件,第一个是函数版本,第二个是模板版本。每个源文件都有 2 个带有关联输出的附加编译器。每个源文件的两个附加编译器之间的唯一区别是左侧编译器没有打开编译器标志或优化,而右侧版本 -O3
设置为打开 3 级优化。
这是我的功能:
// Function Version
int factorial(int n) {
if (n == 0 || n == 1) return 1;
if (n == 2) return 2;
return (n * factorial(n-1));
}
// Template Version:
template<unsigned N>
static auto constexpr factorial_t() {
return (N * factorial<N-1>());
}
template<>
auto constexpr factorial_t<0>() {
return 1;
}
template<>
auto constexpr factorial_t<1>() {
return 1;
}
template<>
auto constexpr factorial_t<2>() {
return 2;
}
现在,当我使用 c++17
在本地 PC 上 运行 安装 IDE
Visual Studio 2017
时,我得到了预期的输出 return从 main()
返回,并且 returned 值对于两种实现都是正确的。
我将其移植到 Compiler Explorer 以测试其他编译器及其优化,以比较它们生成的汇编指令。这是一个相当简单的过程。
现在当我 运行 这些功能时:
来源#1
int main() {
return factorial(6);
}
来源#2
int main() {
return factorial_t<6>();
}
编译器资源管理器生成以下指令计数...
| Assembly Instruction Count |
Type | Without O3 | With O3 Turned On |
Function | 34 | 29 |
Template | 50 | 3 |
一切都很好。
所有四个程序执行return一个值208
。
现在回答我的问题:
然而,在第一个和第三个编译器的汇编中,如果不做一些寄存器数学运算,这并不明显,但是在第二个也是最后一个,-O3
为 function
和 template
版本,值 720
在 main()
的 return 调用之前被存储到 EAX
寄存器中。为什么编译器资源管理器显示:Program returned: 208
而不是 720
?