Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译器是否决定何时内联函数(在C+;+;)中?_C++_Compiler Theory_Compiler Optimization - Fatal编程技术网

C++ 编译器是否决定何时内联函数(在C+;+;)中?

C++ 编译器是否决定何时内联函数(在C+;+;)中?,c++,compiler-theory,compiler-optimization,C++,Compiler Theory,Compiler Optimization,我知道您可以使用inline关键字,也可以将方法放在类声明或getter方法中,但是编译器是否最终决定何时内联我的方法 例如: inline void Foo::vLongBar() { //several function calls and lines of code } 如果编译器认为内联声明会使代码效率低下,它会忽略我的内联声明吗 作为附带问题,如果我在类外声明了一个getter方法,如下所示: void Foo::bar() { std::cout << "baz"

我知道您可以使用inline关键字,也可以将方法放在类声明或getter方法中,但是编译器是否最终决定何时内联我的方法

例如:

inline void Foo::vLongBar()
{
   //several function calls and lines of code
}
如果编译器认为内联声明会使代码效率低下,它会忽略我的内联声明吗

作为附带问题,如果我在类外声明了一个getter方法,如下所示:

void Foo::bar() { std::cout << "baz"; }

<代码>无效Fo::{):STD::CUT< P>是的,是否将内嵌代码的最终决定权在于C++编译器。内联关键字是建议,而不是要求。

下面是关于微软C++编译器中如何处理这个决定的一些细节

一天结束时,函数是否内联完全取决于 编译器。通常情况下,函数在流方面越复杂,编译器内联它的可能性就越小。有些函数,例如递归函数,根本无法内联

不内联函数的主要原因是,它将大大增加代码的总体大小,防止iot被保存在处理器的缓存中。这实际上是一种悲观,而不是优化


至于让程序员决定自杀,或者在其他地方,你可以自己内联函数——在函数的调用站点编写函数中的代码。

据我所知,编译器会自动生成你声明的内联函数(或写在类声明中)如果它找到类似for、while等的循环,则为非内联。
这是编译器在内联函数中拥有最后发言权的一个例子。

是的,编译器拥有最终决定权。;)


正如许多人已经发布的那样,最终的决定总是由编译器做出的,即使您可以给出诸如forceinline之类的明确提示。
部分原因是内联不是一个自动的“更快”切换。过多的内联会使代码变得更大,并可能干扰其他优化。请参阅

作为附带问题,如果我在类外声明了一个getter方法,如下所示:

void Foo::bar() { std::cout << "baz"; }

void Foo::bar(){std::cout正如其他人所指出的那样,
inline
关键字只是建议编译器内联代码。由于编译器通常内联未标记为
inline
的代码,而不是内联代码,因此该关键字似乎与
register
或(C++0x之前)
自动


但是,
inline
关键字还有一个作用:它改变了函数从外部的链接(函数的默认值)内联链接允许每个编译单元包含它自己的目标代码副本,并让链接器从最终可执行文件中删除冗余副本。如果这让你想起模板,是的,模板也使用内联链接。

只是为了增加我的5美分

我发现这篇关于内联的文章非常有用


据我记忆所及,我在某个地方读到,当链接器链接目标文件并发现链接的代码可以内联时,即使链接器也可能进行内联。

如果您确实、肯定、绝对地需要内联代码,则始终存在宏。C多年来一直支持这些,因为它们只是文本替换在编译之前,它们真的,真的,内联你写的任何东西

这就是为什么“inline”关键字(在某些情况下,甚至是强制变量)没有一种标准的强制方式的原因——您总是可以编写一个宏


这是说,内联关键字通常更好,因为编译器经常知道如果函数内联是有意义的,或者因为内联可以与编译器优化的其余部分交互。

你能详细说明为什么吗?我认为C++的目的是给程序员足够的绳子来挂起自己,但是这是S。eems限制性。有什么好的理由吗?@Hooked,看看我发布的链接。它详细说明了为什么这并不总是一件好事。我想到的第一个问题是头递归函数。标准规定,即使forceinline没有结束争论,编译器仍然有最终决定权。当我nlining是不合适的,但如果程序员/探查器决定超越编译器,他的选项是什么?该链接没有详细说明让编译器决定的理由。可能根本不可能内联给定的函数。也就是说,应该注意的是,一些编译器至少仍然为您提供了重写fi的方法nal决策-例如VC++中的
\uu forceinline
。这仍然不允许您内联不可能内联的函数,但它将覆盖编译器的成本/收益分析。请参阅我对JaredPar答案的评论。递归函数可以内联到指定的深度:)编译器如何知道编译时的深度是多少?@Neil Butterworth:我假设编译器可以看到如果迭代次数是常量或常量表达式,那么会有多少次迭代。从msdn页面上看,内联递归的扩展次数似乎比实际需要的要多。看起来很可能是pessimation(就代码大小而言)比优化(就性能而言)多出一倍哦,amd顺便说一句,你能不能不要在你的每一条评论后面都加上一个笑脸?你的答案后面甚至还有一个笑脸!我…你有任何来源来支持这个说法吗?一个循环?为什么是循环?你不是指递归吗?它是特定于实现的。标准没有说明函数什么时候可能没有内联;只有实现h作为最后的决定。哦,我不知道。我不知道链接器到底做什么(我已经被我喜欢的IDE宠坏了,
void Foo::bar() { std::cout << "baz"; }