gcc 拒绝内联请求
gcc denying inline request
#include <iostream>
using namespace std;
inline int square(int n)
{
return n * n;
}
int main(void)
{
cout << square(2) << endl;
}
通过使用 gcc 编译代码,我发现编译器仍然将 square 函数视为简单函数而不是内联函数。
(我检查了汇编代码,在那里我看到了对 square 函数的调用。这就是我知道它没有将其视为内联的方式。)
为什么它拒绝我将函数内联的请求,即使它是一个简单的函数?
如果 gcc 拒绝内联这样一个简单的函数,那么 inline 关键字有什么用?
我可以强制内联函数;那不是问题。我只想知道为什么 gcc 拒绝我的请求。
inline
在现代主流编译器中基本上被忽略了(它只启用 the usual exemption to the ODR for the function)。优化器无论如何都会做他的事情,它可能比你或我更清楚(尽管通常有一些特定于编译器的标志来强制内联函数)。
无论如何,您可能在那里没有看到任何内联,因为您在编译时禁用了优化 - 这是调试中经常使用的设置,其中内联和其他优化使得无法将源代码行与编译代码匹配(因此在调试器)。在我的机器 (g++ 4.8.4) 上启用优化 -O3
使函数完全消失 - 结果 (4
) 在编译时完全评估。
总结一下:目前,inline
的要点是允许您在多个翻译单元中提供函数定义,而不会出现 link 函数的多个定义错误。
这很有用,因为如果你有一个很好的内联候选者,你想将它放入头文件中(这样编译每个 .cpp
编译器可以立即看到它的定义,并立即将其内联展开- link 时间码生成只是最近的事情)但是你想让 link 人知道出现的额外的非 inline
副本都指的是同一件事,并且可以是安全丢弃(将它们标记为 static
会导致每个 TU 中不必要的代码重复)。
编译优化,例如g++ -O3 ...
.
您没有在启用优化的情况下进行编译。即使使用 -O1
,您的代码也会编译为
int main () {
std::cout << 4;
}
此外,您不必担心什么应该内联什么不应该内联,让编译器为您做。它 方式 更好。 (一如既往,除非你通过测量证明编译器是错误的。)
#include <iostream>
using namespace std;
inline int square(int n)
{
return n * n;
}
int main(void)
{
cout << square(2) << endl;
}
通过使用 gcc 编译代码,我发现编译器仍然将 square 函数视为简单函数而不是内联函数。
(我检查了汇编代码,在那里我看到了对 square 函数的调用。这就是我知道它没有将其视为内联的方式。)
为什么它拒绝我将函数内联的请求,即使它是一个简单的函数? 如果 gcc 拒绝内联这样一个简单的函数,那么 inline 关键字有什么用?
我可以强制内联函数;那不是问题。我只想知道为什么 gcc 拒绝我的请求。
inline
在现代主流编译器中基本上被忽略了(它只启用 the usual exemption to the ODR for the function)。优化器无论如何都会做他的事情,它可能比你或我更清楚(尽管通常有一些特定于编译器的标志来强制内联函数)。
无论如何,您可能在那里没有看到任何内联,因为您在编译时禁用了优化 - 这是调试中经常使用的设置,其中内联和其他优化使得无法将源代码行与编译代码匹配(因此在调试器)。在我的机器 (g++ 4.8.4) 上启用优化 -O3
使函数完全消失 - 结果 (4
) 在编译时完全评估。
总结一下:目前,inline
的要点是允许您在多个翻译单元中提供函数定义,而不会出现 link 函数的多个定义错误。
这很有用,因为如果你有一个很好的内联候选者,你想将它放入头文件中(这样编译每个 .cpp
编译器可以立即看到它的定义,并立即将其内联展开- link 时间码生成只是最近的事情)但是你想让 link 人知道出现的额外的非 inline
副本都指的是同一件事,并且可以是安全丢弃(将它们标记为 static
会导致每个 TU 中不必要的代码重复)。
编译优化,例如g++ -O3 ...
.
您没有在启用优化的情况下进行编译。即使使用 -O1
,您的代码也会编译为
int main () {
std::cout << 4;
}
此外,您不必担心什么应该内联什么不应该内联,让编译器为您做。它 方式 更好。 (一如既往,除非你通过测量证明编译器是错误的。)