Jon*_*Mee 85 c++ methods inline function deprecated
我相信,inline已经过时,因为我在这里读到:
无论你如何指定一个函数
inline,它都是一个允许编译器忽略的请求:编译器可能内联扩展一些,全部或没有你调用指定函数的地方inline.
然而,Angew似乎理解我不知道的事情.在这个问题中他和我来回走了很多,关于是否inline仍然有用.
这个问题不是一个问题:
inline或在哪里inline仍可用于向编译器提示inline功能:我应该何时为函数/方法编写关键字'inline'?.inline运行代码:强制其他翻译单元中的内联函数请记住,编译器可以随意使用inline,因此inline在那里没有用处:可以inline用来强制而不是建议编译代码的更改?
Rei*_*ica 77
我会尝试以最好的方式解释我的"秘密理解".
这里有两个完全独立的概念.一个是编译器通过直接在调用站点重复函数体来替换函数调用的能力.另一种是可以在多个翻译单元中定义一个函数(=多个.cpp文件).
第一个称为函数内联.第二个是inline关键字的目的.从历史上看,该inline关键字也是一个强烈的建议,它应内嵌标记功能的编译器inline.随着编译器在优化方面变得更好,这个功能已经退去,并且使用inline作为内联函数的建议确实已经过时了.如果发现这是一个更好的优化,编译器将很乐意忽略它并完全内联其他内容.
我希望我们已经处理了明确的内inline联关系.当前代码中没有.
那么,inline关键字的实际目的是什么?这很简单:标记的功能inline可以在多个翻译单元中定义,而不违反单一定义规则(ODR).想象一下这两个文件:
file1.cpp
int f() { return 42; }
int main()
{ return f(); }
Run Code Online (Sandbox Code Playgroud)
file2.cpp
int f() { return 42; }
Run Code Online (Sandbox Code Playgroud)
这个命令:
> gcc file1.cpp file2.cpp
Run Code Online (Sandbox Code Playgroud)
将产生链接器错误,抱怨符号f定义了两次.
但是,如果使用inline关键字标记函数,它会特别告诉编译器和链接器:"你们确保这个函数的多个相同定义不会导致任何错误!"
所以以下内容将起作用:
file1.cpp
inline int f() { return 42; }
int main()
{ return f(); }
Run Code Online (Sandbox Code Playgroud)
file2.cpp
inline int f() { return 42; }
Run Code Online (Sandbox Code Playgroud)
将这两个文件编译并链接在一起不会产生任何链接器错误.
请注意,当然,定义f不必逐字存入文件中.它可以来自#included头文件:
f.hpp
inline int f() { return 42; }
Run Code Online (Sandbox Code Playgroud)
file1.cpp
#include "f.hpp"
int main()
{ return f(); }
Run Code Online (Sandbox Code Playgroud)
file2.cpp
#include "f.hpp"
Run Code Online (Sandbox Code Playgroud)
基本上,为了能够将函数定义写入头文件,您必须将其标记为inline,否则将导致多个定义错误.
最后一个难题是:为什么关键字inline在与内联无关时实际拼写?原因很简单:内联一个函数(也就是说,通过在调用站点上重复它的主体来替换对它的调用),编译器必须首先拥有函数的主体.
C++遵循单独的编译模型,其中编译器不能访问除当前生成的目标文件之外的目标文件.因此,为了能够内联函数,其定义必须是当前翻译单元的一部分.如果您希望能够在多个翻译单元中对其进行内联,则其定义必须包含在所有翻译单元中.通常,这会导致多重定义错误.因此,如果将函数放在标题中并将#include其定义放在任何地方以使其在任何地方都能内联,则必须将其标记为inline防止出现多个定义错误.
请注意,即使在今天,虽然编译器将内联任何函数看起来合适,但它仍然必须能够访问该函数的定义.因此,虽然inline不需要关键字作为提示"请内联这个",但您可能仍然发现需要使用它来使编译器在选择这样做的情况下进行内联.没有它,您可能无法将定义放入转换单元,如果没有定义,编译器就无法内联函数.
编译器不能.链接器可以.现代优化技术包括链接时代码生成(也称为整个程序优化),其中优化器在实际链接之前作为链接过程的一部分在所有目标文件上运行.在此步骤中,所有函数定义当然都是可用的,并且如果没有inline在程序中的任何位置使用单个关键字,则完全可以进行内联.但是这种优化在构建时通常很昂贵,特别是对于大型项目.考虑到这一点,完全依靠LTCG进行内联可能不是最好的选择.
为了完整性:我在第一部分中略有欺骗.ODR属性实际上不是inline关键字的属性,而是内联函数(这是语言的术语)的属性.内联函数的规则是:
的inline关键字把函数到一个内联函数.将函数标记为内联的另一种方法是直接在类定义中定义(而不仅仅是声明)它.即使没有inline关键字,这样的函数也会自动内联.
Luc*_*ore 45
inline 由于你说的原因,现在大多只是一个外部链接说明符.
所以是的,它确实有用,但它与实际内联函数不同.它允许您在编译单元之间多次定义相同的方法并将它们正确地链接在一起,而不是获得多个定义错误.
//header.h
inline void foo() {}
void goo() {}
//cpp1.cpp
#include "header.h"
//cpp2.cpp
#include "header.h"
// foo is okay, goo breaks the one definition rule (ODR)
Run Code Online (Sandbox Code Playgroud)
实际上强制函数内联取决于编译器,有些可能通过特定的attributes或pragmas或(__forceinline)或诸如此类的东西支持.
简而言之,它允许您在不破坏ODR的情况下在标题中定义函数...
| 归档时间: |
|
| 查看次数: |
15704 次 |
| 最近记录: |