c++中内联函数的好处?

时间:2021-08-18 00:10:41

What is the advantages/disadvantages of using inline functions in C++? I see that it only increases performance for the code that the compiler outputs, but with today's optimized compilers, fast CPUs, huge memory etc. (not like in the 1980< where memory was scarce and everything had to fit in 100KB of memory) what advantages do they really have today?

在c++中使用内联函数的优点和缺点是什么?我看到它只会提高编译器输出的代码的性能,但是在今天的优化编译器、快速cpu、巨大内存等(不像1980年 <内存不足,所有东西都必须装入100kb内存)的情况下,它们现在有什么优势呢?< p>

14 个解决方案

#1


136  

Inline functions are faster because you don't need to push and pop things on/off the stack like parameters and the return address; however, it does make your binary slightly larger.

内联函数更快,因为您不需要像参数和返回地址那样在堆栈上或堆栈上推送或弹出内容;但是,它确实使二进制数稍微大一些。

Does it make a significant difference? Not noticeably enough on modern hardware for most. But it can make a difference, which is enough for some people.

这有很大的不同吗?对大多数现代硬件来说还不够明显。但它能带来改变,这对一些人来说已经足够了。

Marking something inline does not give you a guarantee that it will be inline. It's just a suggestion to the compiler. Sometimes it's not possible such as when you have a virtual function, or when there is recursion involved. And sometimes the compiler just chooses not to use it.

标记一些内联的东西并不能保证它是内联的。这只是给编译器的建议。有时这是不可能的,比如当你有一个虚拟函数时,或者当涉及到递归时。有时候编译器会选择不使用它。

I could see a situation like this making a detectable difference:

我可以看到这样的情况会产生明显的不同:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

#2


191  

Advantages

  • By inlining your code where it is needed, your program will spend less time in the function call and return parts. It is supposed to make your code go faster, even as it goes larger (see below). Inlining trivial accessors could be an example of effective inlining.
  • 通过在需要的地方内联代码,您的程序将在函数调用和返回部分上花费更少的时间。它应该使您的代码运行得更快,即使它变得更大(参见下面)。内联小访问器是有效内联的一个例子。
  • By marking it as inline, you can put a function definition in a header file (i.e. it can be included in multiple compilation unit, without the linker complaining)
  • 通过将它标记为内联,您可以将函数定义放在头文件中(例如,它可以包含在多个编译单元中,而不会引起链接器的抱怨)

Disadvantages

  • It can make your code larger (i.e. if you use inline for non-trivial functions). As such, it could provoke paging and defeat optimizations from the compiler.
  • 它可以使您的代码更大(例如,如果您对非平凡函数使用内联)。因此,它可能引发分页并破坏编译器的优化。
  • It slightly breaks your encapsulation because it exposes the internal of your object processing (but then, every "private" member would, too). This means you must not use inlining in a PImpl pattern.
  • 它稍微破坏了封装,因为它公开了对象处理的内部(但是,每个“private”成员也会这样做)。这意味着您不能在PImpl模式中使用内联。
  • It slightly breaks your encapsulation 2: C++ inlining is resolved at compile time. Which means that should you change the code of the inlined function, you would need to recompile all the code using it to be sure it will be updated (for the same reason, I avoid default values for function parameters)
  • 它稍微破坏了封装2:c++内联在编译时解析。这意味着,如果修改内联函数的代码,就需要重新编译使用它的所有代码,以确保它将被更新(出于同样的原因,我避免使用函数参数的默认值)
  • When used in a header, it makes your header file larger, and thus, will dilute interesting informations (like the list of a class methods) with code the user don't care about (this is the reason that I declare inlined functions inside a class, but will define it in an header after the class body, and never inside the class body).
  • 标题中使用时,它会让你的头文件较大,因此,将稀释有趣的信息(比如一个类的列表方法)与代码的用户不关心(这是原因,我声明内联函数在一个类,但它将定义在一个头下课后的身体,而且从不类体内)。

Inlining Magic

  • The compiler may or may not inline the functions you marked as inline; it may also decide to inline functions not marked as inline at compilation or linking time.
  • 编译器可以或不可以内联您标记为内联的函数;它还可以决定在编译或链接时不以内联方式标记内联函数。
  • Inline works like a copy/paste controlled by the compiler, which is quite different from a pre-processor macro: The macro will be forcibly inlined, will pollute all the namespaces and code, won't be easily debuggable, and will be done even if the compiler would have ruled it as inefficient.
  • 内联的工作方式类似于编译器控制的复制/粘贴,这与预处理器宏非常不同:宏会被强制内联,会污染所有的名称空间和代码,不会很容易调试,即使编译器认为它效率很低,也会这样做。
  • Every method of a class defined inside the body of the class itself is considered as "inlined" (even if the compiler can still decide to not inline it
  • 在类本身的主体中定义的类的每个方法都被认为是“内联的”(即使编译器仍然可以决定不内联它)
  • Virtual methods are not supposed to be inlinable. Still, sometimes, when the compiler can know for sure the type of the object (i.e. the object was declared and constructed inside the same function body), even a virtual function will be inlined because the compiler knows exactly the type of the object.
  • 虚拟方法不应该是不可行的。但是,有时,当编译器可以确定对象的类型(即在同一个函数体中声明和构造对象)时,即使是一个虚拟函数也会被内联,因为编译器知道对象的类型。
  • Template methods/functions are not always inlined (their presence in an header will not make them automatically inline).
  • 模板方法/函数并不总是内联的(它们出现在header中不会自动内联)。
  • The next step after "inline" is template metaprograming . I.e. By "inlining" your code at compile time, sometimes, the compiler can deduce the final result of a function... So a complex algorithm can sometimes be reduced to a kind of return 42 ; statement. This is for me extreme inlining. It happens rarely in real life, it makes compilation time longer, will not bloat your code, and will make your code faster. But like the grail, don't try to apply it everywhere because most processing cannot be resolved this way... Still, this is cool anyway...
    :-p
  • “inline”之后的下一步是模板元编程。例如,通过在编译时“内联”代码,有时编译器可以推断出函数的最终结果……所以一个复杂的算法有时可以简化为返回42;声明。这是我的极端内联。它在现实生活中很少发生,它使编译时间更长,不会膨胀代码,并且会使代码更快。但是,就像圣杯一样,不要试图将它应用到任何地方,因为大多数处理不能通过这种方式解决……不管怎样,这还是很酷的……:- p

#3


37  

In archaic C and C++, inline is like register: a suggestion (nothing more than a suggestion) to the compiler about a possible optimization.

在古体的C和c++中,内联就像寄存器:对编译器关于可能的优化的建议(只不过是一个建议)。

In modern C++, inline tells the linker that, if multiple definitions (not declarations) are found in different translation units, they are all the same, and the linker can freely keep one and discard all the other ones.

在现代c++中,inline告诉链接器,如果在不同的翻译单元中发现多个定义(而不是声明),那么它们都是相同的,链接器可以*地保留一个定义,并丢弃所有其他定义。

inline is mandatory if a function (no matter how complex or "linear") is defined in a header file, to allow multiple sources to include it without getting a "multiple definition" error by the linker.

如果在头文件中定义一个函数(无论多么复杂或“线性”),允许多个源包含它,而链接器不会产生“多重定义”错误,则内联是必需的。

Member functions defined inside a class are "inline" by default, as are template functions (in contrast to global functions).

在类内定义的成员函数默认为“内联”,模板函数(与全局函数相反)。

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

Note the inclusion of fileA.h into two .cpp files, resulting in two instances of afunc(). The linker will discard one of them. If no inline is specified, the linker will complain.

注意文件的包含。h变成两个.cpp文件,导致afunc()的两个实例。链接器会丢弃其中一个。如果没有指定内联,链接器会抱怨。

#4


16  

Inlining is a suggestion to the compiler which it is free to ignore. It's ideal for small bits of code.

内联是对编译器的一种建议,它可以随意忽略。对于小段代码来说,它是理想的。

If your function is inlined, it's basically inserted in the code where the function call is made to it, rather than actually calling a separate function. This can assist with speed as you don't have to do the actual call.

如果你的函数是内联的,它会被插入到函数调用的代码中,而不是调用一个单独的函数。这可以帮助您提高速度,因为您不必执行实际的调用。

It also assists CPUs with pipelining as they don't have to reload the pipeline with new instructions caused by a call.

它还帮助cpu使用流水线操作,因为它们不需要用调用引起的新指令重新加载管道。

The only disadvantage is possible increased binary size but, as long as the functions are small, this won't matter too much.

唯一的缺点是可能增加二进制大小,但只要函数很小,这就不会太重要。

I tend to leave these sorts of decisions to the compilers nowadays (well, the smart ones anyway). The people who wrote them tend to have far more detailed knowledge of the underlying architectures.

我现在倾向于把这些决定留给编译器(不管怎样,聪明的编译器)。编写它们的人往往对底层架构有更详细的了解。

#5


12  

Inline function is the optimization technique used by the compilers. One can simply prepend inline keyword to function prototype to make a function inline. Inline function instruct compiler to insert complete body of the function wherever that function got used in code.

内联函数是编译器使用的优化技术。可以简单地将inline关键字前置到函数原型,以使函数内联。内联函数指示编译器在代码中使用该函数的任何地方插入完整的函数体。

Advantages :-

优点:-

  1. It does not require function calling overhead.

    它不需要函数调用开销。

  2. It also save overhead of variables push/pop on the stack, while function calling.

    它还可以在函数调用时,在堆栈上保存变量push/pop的开销。

  3. It also save overhead of return call from a function.

    它还可以从函数中节省返回调用的开销。

  4. It increases locality of reference by utilizing instruction cache.

    它通过使用指令缓存增加引用的位置。

  5. After in-lining compiler can also apply intra-procedural optimization if specified. This is the most important one, in this way compiler can now focus on dead code elimination, can give more stress on branch prediction, induction variable elimination etc..

    内联编译器也可以在指定的情况下应用过程内优化。这是最重要的一个,这样编译器现在可以集中于死代码消除,可以在分支预测、归纳变量消除等方面给予更多的压力。

To check more about it one can follow this link http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html

要查看更多信息,可以访问这个链接http://tajendrasengar.blogspot.com/2010/03/what-is-inline- functionin -cc.html

#6


6  

I'd like to add that inline functions are crucial when you are building shared library. Without marking function inline, it will be exported into the library in the binary form. It will be also present in the symbols table, if exported. On the other side, inlined functions are not exported, neither to the library binaries nor to the symbols table.

我想补充一点,当您构建共享库时,内联函数是至关重要的。如果没有对函数内联进行标记,它将以二进制形式导出到库中。如果导出,它也将显示在symbols表中。另一方面,内联函数不导出,既不导出到库二进制文件,也不导出到符号表。

It may be critical when library is intended to be loaded at runtime. It may also hit binary-compatible-aware libraries. In such cases don't use inline.

当库打算在运行时加载时,它可能是关键的。它也可能会攻击支持二进制兼容性的库。在这种情况下不使用内联。

#7


4  

During optimization many compilers will inline functions even if you didn't mark them. You generally only need to mark functions as inline if you know something the compiler doesn't, as it can usually make the correct decision itself.

在优化过程中,许多编译器将内联函数,即使您没有标记它们。如果您知道编译器不知道的内容,通常只需要将函数标记为内联,因为它通常可以自己做出正确的决策。

#8


4  

inline allows you to place a function definition in a header file and #include that header file in multiple source files without violating the one definition rule.

inline允许您在头文件中放置一个函数定义,而#将头文件包含在多个源文件中,而不违反一个定义规则。

#9


3  

Generally speaking, these days with any modern compiler worrying about inlining anything is pretty much a waste of time. The compiler should actually optimize all of these considerations for you through its own analysis of the code and your specification of the optimization flags passed to the compiler. If you care about speed, tell the compiler to optimize for speed. If you care about space, tell the compiler to optimize for space. As another answer alluded to, a decent compiler will even inline automatically if it really makes sense.

一般来说,现在任何现代编译器都担心内联,这几乎是在浪费时间。编译器实际上应该通过对代码的分析和对传递给编译器的优化标志的规范来为您优化所有这些注意事项。如果您关心速度,请告诉编译器优化速度。如果你关心空间,告诉编译器优化空间。正如另一个答案所暗示的,如果一个好的编译器真的有意义的话,它甚至会自动地内联。

Also, as others have stated, using inline does not guarantee inline of anything. If you want to guarantee it, you will have to define a macro instead of an inline function to do it.

另外,正如其他人所说,使用inline并不保证任何东西都是内联的。如果你想保证它,你需要定义一个宏而不是内联函数。

When to inline and/or define a macro to force inclusion? - Only when you have a demonstrated and necessary proven increase in speed for a critical section of code that is known to have an affect on the overall performance of the application.

何时内联和/或定义宏以强制包含?-只有当你有一个已经证明且必要的速度的证明时,一个关键的代码段的速度会增加,而这段代码对应用程序的整体性能有影响。

#10


3  

It is not all about performance. Both C++ and C are used for embedded programming, sitting on top of hardware. If you would, for example, write an interrupt handler, you need to make sure that the code can be executed at once, without additional registers and/or memory pages being being swapped. That is when inline comes in handy. Good compilers do some "inlining" themselves when speed is needed, but "inline" compels them.

这并不全是性能的问题。c++和C都用于嵌入式编程,位于硬件之上。例如,如果要编写中断处理程序,则需要确保可以立即执行代码,而不交换其他寄存器和/或内存页。这就是内联派上用场的时候。当需要速度时,好的编译器会自己进行一些“内联”操作,但是“内联”会迫使它们这样做。

#11


1  

Fell into the same trouble with inlining functions into so libraries. It seems that inlined functions are not compiled into the library. as a result the linker puts out a "undefined reference" error, if a executable wants to use the inlined function of the library. (happened to me compiling Qt source with gcc 4.5.

将函数内联到so库中也遇到了同样的问题。似乎内联函数没有编译到库中。因此,如果一个可执行程序想要使用库的内联函数,那么链接器就会发出一个“未定义的引用”错误。(碰巧我用gcc 4.5编译Qt源代码。

#12


1  

Why not make all functions inline by default? Because it's an engineering trade off. There are at least two types of "optimization": speeding up the program and reducing the size (memory footprint) of the program. Inlining generally speeds things up. It gets rid of the function call overhead, avoiding pushing then pulling parameters from the stack. However, it also makes the memory footprint of the program bigger, because every function call must now be replaced with the full code of the function. To make things even more complicated, remember that the CPU stores frequently used chunks of memory in a cache on the CPU for ultra-rapid access. If you make the program's memory image big enough, your program won't be able to use the cache efficiently, and in the worst case inlining could actually slow your program down. To some extent the compiler can calculate what the trade offs are, and may be able to make better decisions than you can, just looking at the source code.

为什么不在默认情况下让所有的函数都是内联的呢?因为这是一种工程权衡。至少有两种类型的“优化”:加速程序和减少程序的大小(内存占用)。内联通常会加快速度。它消除了函数调用开销,避免了从堆栈中提取参数。但是,它也使程序的内存占用更大,因为现在必须用函数的完整代码替换每个函数调用。要使事情变得更复杂,请记住,CPU在CPU上的缓存中存储频繁使用的内存块,以便进行超高速访问。如果使程序的内存映像足够大,程序将无法有效地使用缓存,而且在最坏的情况下,内联实际上可能会降低程序的速度。在某种程度上,编译器可以计算出权衡的结果,并且可能能够做出比你所能做的更好的决定,只是看看源代码。

#13


1  

Our computer science professor urged us to never use inline in a c++ program. When asked why, he kindly explained to use that modern compilers should detect when to use inline automatically.

我们的计算机科学教授敦促我们不要在c++程序中使用内联。当被问及原因时,他和蔼地解释说,现代编译器应该检测什么时候自动使用内联。

So yes, the inline can be an optimization technique to be used wherever possible, but apparently this is something that is already done for you whenever it's possible to inline a function anyways.

是的,内联可以是一种优化技术,在任何可能的情况下都可以使用,但显然这是已经为您做过的,无论何时,只要有可能内联一个函数。

#14


-1  

Conclusion from another discussion here:

从另一个讨论的结论:

Are there any drawbacks with inline functions?

内联函数有什么缺点吗?

Apparently, There is nothing wrong with using inline functions.

显然,使用内联函数没有什么错。

But it is worth noting the following points!

但值得注意的是以下几点!

  • Overuse of inlining can actually make programs slower. Depending on a function's size, inlining it can cause the code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs faster due to better use of the instruction cache. - Google Guidelines

    过度使用内联实际上会使程序变慢。根据函数的大小,内联可以使代码大小增加或减少。内联一个非常小的访问函数通常会减少代码大小,而内联一个非常大的函数可以显著增加代码大小。在现代处理器中,由于更好地使用指令缓存,较小的代码通常运行得更快。——谷歌指南

  • The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost - Source

    内联函数的速度优势随着函数的增大而减小。在某些时候,与执行函数体相比,函数调用的开销变得很小,并且好处是丢失了源

  • There are few situations where an inline function may not work:

    有一些情况下,内联函数可能不能工作:

    • For a function returning values; if a return statement exists.
    • 函数返回值;如果存在返回语句。
    • For a function not returning any values; if a loop, switch or goto statement exists.
    • 对于不返回任何值的函数;如果存在循环,则切换或goto语句。
    • If a function is recursive. -Source
    • 如果函数是递归的。源
  • The __inline keyword causes a function to be inlined only if you specify the optimize option. If optimize is specified, whether or not __inline is honored depends on the setting of the inline optimizer option. By default, the inline option is in effect whenever the optimizer is run. If you specify optimize , you must also specify the noinline option if you want the __inline keyword to be ignored. -Source

    __inline关键字只在指定优化选项时才会使函数内联。如果指定了优化,那么是否使用__inline取决于内联优化器选项的设置。默认情况下,无论何时运行优化器,inline选项都是有效的。如果要忽略__inline关键字,则还必须指定noinline选项。源

#1


136  

Inline functions are faster because you don't need to push and pop things on/off the stack like parameters and the return address; however, it does make your binary slightly larger.

内联函数更快,因为您不需要像参数和返回地址那样在堆栈上或堆栈上推送或弹出内容;但是,它确实使二进制数稍微大一些。

Does it make a significant difference? Not noticeably enough on modern hardware for most. But it can make a difference, which is enough for some people.

这有很大的不同吗?对大多数现代硬件来说还不够明显。但它能带来改变,这对一些人来说已经足够了。

Marking something inline does not give you a guarantee that it will be inline. It's just a suggestion to the compiler. Sometimes it's not possible such as when you have a virtual function, or when there is recursion involved. And sometimes the compiler just chooses not to use it.

标记一些内联的东西并不能保证它是内联的。这只是给编译器的建议。有时这是不可能的,比如当你有一个虚拟函数时,或者当涉及到递归时。有时候编译器会选择不使用它。

I could see a situation like this making a detectable difference:

我可以看到这样的情况会产生明显的不同:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

#2


191  

Advantages

  • By inlining your code where it is needed, your program will spend less time in the function call and return parts. It is supposed to make your code go faster, even as it goes larger (see below). Inlining trivial accessors could be an example of effective inlining.
  • 通过在需要的地方内联代码,您的程序将在函数调用和返回部分上花费更少的时间。它应该使您的代码运行得更快,即使它变得更大(参见下面)。内联小访问器是有效内联的一个例子。
  • By marking it as inline, you can put a function definition in a header file (i.e. it can be included in multiple compilation unit, without the linker complaining)
  • 通过将它标记为内联,您可以将函数定义放在头文件中(例如,它可以包含在多个编译单元中,而不会引起链接器的抱怨)

Disadvantages

  • It can make your code larger (i.e. if you use inline for non-trivial functions). As such, it could provoke paging and defeat optimizations from the compiler.
  • 它可以使您的代码更大(例如,如果您对非平凡函数使用内联)。因此,它可能引发分页并破坏编译器的优化。
  • It slightly breaks your encapsulation because it exposes the internal of your object processing (but then, every "private" member would, too). This means you must not use inlining in a PImpl pattern.
  • 它稍微破坏了封装,因为它公开了对象处理的内部(但是,每个“private”成员也会这样做)。这意味着您不能在PImpl模式中使用内联。
  • It slightly breaks your encapsulation 2: C++ inlining is resolved at compile time. Which means that should you change the code of the inlined function, you would need to recompile all the code using it to be sure it will be updated (for the same reason, I avoid default values for function parameters)
  • 它稍微破坏了封装2:c++内联在编译时解析。这意味着,如果修改内联函数的代码,就需要重新编译使用它的所有代码,以确保它将被更新(出于同样的原因,我避免使用函数参数的默认值)
  • When used in a header, it makes your header file larger, and thus, will dilute interesting informations (like the list of a class methods) with code the user don't care about (this is the reason that I declare inlined functions inside a class, but will define it in an header after the class body, and never inside the class body).
  • 标题中使用时,它会让你的头文件较大,因此,将稀释有趣的信息(比如一个类的列表方法)与代码的用户不关心(这是原因,我声明内联函数在一个类,但它将定义在一个头下课后的身体,而且从不类体内)。

Inlining Magic

  • The compiler may or may not inline the functions you marked as inline; it may also decide to inline functions not marked as inline at compilation or linking time.
  • 编译器可以或不可以内联您标记为内联的函数;它还可以决定在编译或链接时不以内联方式标记内联函数。
  • Inline works like a copy/paste controlled by the compiler, which is quite different from a pre-processor macro: The macro will be forcibly inlined, will pollute all the namespaces and code, won't be easily debuggable, and will be done even if the compiler would have ruled it as inefficient.
  • 内联的工作方式类似于编译器控制的复制/粘贴,这与预处理器宏非常不同:宏会被强制内联,会污染所有的名称空间和代码,不会很容易调试,即使编译器认为它效率很低,也会这样做。
  • Every method of a class defined inside the body of the class itself is considered as "inlined" (even if the compiler can still decide to not inline it
  • 在类本身的主体中定义的类的每个方法都被认为是“内联的”(即使编译器仍然可以决定不内联它)
  • Virtual methods are not supposed to be inlinable. Still, sometimes, when the compiler can know for sure the type of the object (i.e. the object was declared and constructed inside the same function body), even a virtual function will be inlined because the compiler knows exactly the type of the object.
  • 虚拟方法不应该是不可行的。但是,有时,当编译器可以确定对象的类型(即在同一个函数体中声明和构造对象)时,即使是一个虚拟函数也会被内联,因为编译器知道对象的类型。
  • Template methods/functions are not always inlined (their presence in an header will not make them automatically inline).
  • 模板方法/函数并不总是内联的(它们出现在header中不会自动内联)。
  • The next step after "inline" is template metaprograming . I.e. By "inlining" your code at compile time, sometimes, the compiler can deduce the final result of a function... So a complex algorithm can sometimes be reduced to a kind of return 42 ; statement. This is for me extreme inlining. It happens rarely in real life, it makes compilation time longer, will not bloat your code, and will make your code faster. But like the grail, don't try to apply it everywhere because most processing cannot be resolved this way... Still, this is cool anyway...
    :-p
  • “inline”之后的下一步是模板元编程。例如,通过在编译时“内联”代码,有时编译器可以推断出函数的最终结果……所以一个复杂的算法有时可以简化为返回42;声明。这是我的极端内联。它在现实生活中很少发生,它使编译时间更长,不会膨胀代码,并且会使代码更快。但是,就像圣杯一样,不要试图将它应用到任何地方,因为大多数处理不能通过这种方式解决……不管怎样,这还是很酷的……:- p

#3


37  

In archaic C and C++, inline is like register: a suggestion (nothing more than a suggestion) to the compiler about a possible optimization.

在古体的C和c++中,内联就像寄存器:对编译器关于可能的优化的建议(只不过是一个建议)。

In modern C++, inline tells the linker that, if multiple definitions (not declarations) are found in different translation units, they are all the same, and the linker can freely keep one and discard all the other ones.

在现代c++中,inline告诉链接器,如果在不同的翻译单元中发现多个定义(而不是声明),那么它们都是相同的,链接器可以*地保留一个定义,并丢弃所有其他定义。

inline is mandatory if a function (no matter how complex or "linear") is defined in a header file, to allow multiple sources to include it without getting a "multiple definition" error by the linker.

如果在头文件中定义一个函数(无论多么复杂或“线性”),允许多个源包含它,而链接器不会产生“多重定义”错误,则内联是必需的。

Member functions defined inside a class are "inline" by default, as are template functions (in contrast to global functions).

在类内定义的成员函数默认为“内联”,模板函数(与全局函数相反)。

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

Note the inclusion of fileA.h into two .cpp files, resulting in two instances of afunc(). The linker will discard one of them. If no inline is specified, the linker will complain.

注意文件的包含。h变成两个.cpp文件,导致afunc()的两个实例。链接器会丢弃其中一个。如果没有指定内联,链接器会抱怨。

#4


16  

Inlining is a suggestion to the compiler which it is free to ignore. It's ideal for small bits of code.

内联是对编译器的一种建议,它可以随意忽略。对于小段代码来说,它是理想的。

If your function is inlined, it's basically inserted in the code where the function call is made to it, rather than actually calling a separate function. This can assist with speed as you don't have to do the actual call.

如果你的函数是内联的,它会被插入到函数调用的代码中,而不是调用一个单独的函数。这可以帮助您提高速度,因为您不必执行实际的调用。

It also assists CPUs with pipelining as they don't have to reload the pipeline with new instructions caused by a call.

它还帮助cpu使用流水线操作,因为它们不需要用调用引起的新指令重新加载管道。

The only disadvantage is possible increased binary size but, as long as the functions are small, this won't matter too much.

唯一的缺点是可能增加二进制大小,但只要函数很小,这就不会太重要。

I tend to leave these sorts of decisions to the compilers nowadays (well, the smart ones anyway). The people who wrote them tend to have far more detailed knowledge of the underlying architectures.

我现在倾向于把这些决定留给编译器(不管怎样,聪明的编译器)。编写它们的人往往对底层架构有更详细的了解。

#5


12  

Inline function is the optimization technique used by the compilers. One can simply prepend inline keyword to function prototype to make a function inline. Inline function instruct compiler to insert complete body of the function wherever that function got used in code.

内联函数是编译器使用的优化技术。可以简单地将inline关键字前置到函数原型,以使函数内联。内联函数指示编译器在代码中使用该函数的任何地方插入完整的函数体。

Advantages :-

优点:-

  1. It does not require function calling overhead.

    它不需要函数调用开销。

  2. It also save overhead of variables push/pop on the stack, while function calling.

    它还可以在函数调用时,在堆栈上保存变量push/pop的开销。

  3. It also save overhead of return call from a function.

    它还可以从函数中节省返回调用的开销。

  4. It increases locality of reference by utilizing instruction cache.

    它通过使用指令缓存增加引用的位置。

  5. After in-lining compiler can also apply intra-procedural optimization if specified. This is the most important one, in this way compiler can now focus on dead code elimination, can give more stress on branch prediction, induction variable elimination etc..

    内联编译器也可以在指定的情况下应用过程内优化。这是最重要的一个,这样编译器现在可以集中于死代码消除,可以在分支预测、归纳变量消除等方面给予更多的压力。

To check more about it one can follow this link http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html

要查看更多信息,可以访问这个链接http://tajendrasengar.blogspot.com/2010/03/what-is-inline- functionin -cc.html

#6


6  

I'd like to add that inline functions are crucial when you are building shared library. Without marking function inline, it will be exported into the library in the binary form. It will be also present in the symbols table, if exported. On the other side, inlined functions are not exported, neither to the library binaries nor to the symbols table.

我想补充一点,当您构建共享库时,内联函数是至关重要的。如果没有对函数内联进行标记,它将以二进制形式导出到库中。如果导出,它也将显示在symbols表中。另一方面,内联函数不导出,既不导出到库二进制文件,也不导出到符号表。

It may be critical when library is intended to be loaded at runtime. It may also hit binary-compatible-aware libraries. In such cases don't use inline.

当库打算在运行时加载时,它可能是关键的。它也可能会攻击支持二进制兼容性的库。在这种情况下不使用内联。

#7


4  

During optimization many compilers will inline functions even if you didn't mark them. You generally only need to mark functions as inline if you know something the compiler doesn't, as it can usually make the correct decision itself.

在优化过程中,许多编译器将内联函数,即使您没有标记它们。如果您知道编译器不知道的内容,通常只需要将函数标记为内联,因为它通常可以自己做出正确的决策。

#8


4  

inline allows you to place a function definition in a header file and #include that header file in multiple source files without violating the one definition rule.

inline允许您在头文件中放置一个函数定义,而#将头文件包含在多个源文件中,而不违反一个定义规则。

#9


3  

Generally speaking, these days with any modern compiler worrying about inlining anything is pretty much a waste of time. The compiler should actually optimize all of these considerations for you through its own analysis of the code and your specification of the optimization flags passed to the compiler. If you care about speed, tell the compiler to optimize for speed. If you care about space, tell the compiler to optimize for space. As another answer alluded to, a decent compiler will even inline automatically if it really makes sense.

一般来说,现在任何现代编译器都担心内联,这几乎是在浪费时间。编译器实际上应该通过对代码的分析和对传递给编译器的优化标志的规范来为您优化所有这些注意事项。如果您关心速度,请告诉编译器优化速度。如果你关心空间,告诉编译器优化空间。正如另一个答案所暗示的,如果一个好的编译器真的有意义的话,它甚至会自动地内联。

Also, as others have stated, using inline does not guarantee inline of anything. If you want to guarantee it, you will have to define a macro instead of an inline function to do it.

另外,正如其他人所说,使用inline并不保证任何东西都是内联的。如果你想保证它,你需要定义一个宏而不是内联函数。

When to inline and/or define a macro to force inclusion? - Only when you have a demonstrated and necessary proven increase in speed for a critical section of code that is known to have an affect on the overall performance of the application.

何时内联和/或定义宏以强制包含?-只有当你有一个已经证明且必要的速度的证明时,一个关键的代码段的速度会增加,而这段代码对应用程序的整体性能有影响。

#10


3  

It is not all about performance. Both C++ and C are used for embedded programming, sitting on top of hardware. If you would, for example, write an interrupt handler, you need to make sure that the code can be executed at once, without additional registers and/or memory pages being being swapped. That is when inline comes in handy. Good compilers do some "inlining" themselves when speed is needed, but "inline" compels them.

这并不全是性能的问题。c++和C都用于嵌入式编程,位于硬件之上。例如,如果要编写中断处理程序,则需要确保可以立即执行代码,而不交换其他寄存器和/或内存页。这就是内联派上用场的时候。当需要速度时,好的编译器会自己进行一些“内联”操作,但是“内联”会迫使它们这样做。

#11


1  

Fell into the same trouble with inlining functions into so libraries. It seems that inlined functions are not compiled into the library. as a result the linker puts out a "undefined reference" error, if a executable wants to use the inlined function of the library. (happened to me compiling Qt source with gcc 4.5.

将函数内联到so库中也遇到了同样的问题。似乎内联函数没有编译到库中。因此,如果一个可执行程序想要使用库的内联函数,那么链接器就会发出一个“未定义的引用”错误。(碰巧我用gcc 4.5编译Qt源代码。

#12


1  

Why not make all functions inline by default? Because it's an engineering trade off. There are at least two types of "optimization": speeding up the program and reducing the size (memory footprint) of the program. Inlining generally speeds things up. It gets rid of the function call overhead, avoiding pushing then pulling parameters from the stack. However, it also makes the memory footprint of the program bigger, because every function call must now be replaced with the full code of the function. To make things even more complicated, remember that the CPU stores frequently used chunks of memory in a cache on the CPU for ultra-rapid access. If you make the program's memory image big enough, your program won't be able to use the cache efficiently, and in the worst case inlining could actually slow your program down. To some extent the compiler can calculate what the trade offs are, and may be able to make better decisions than you can, just looking at the source code.

为什么不在默认情况下让所有的函数都是内联的呢?因为这是一种工程权衡。至少有两种类型的“优化”:加速程序和减少程序的大小(内存占用)。内联通常会加快速度。它消除了函数调用开销,避免了从堆栈中提取参数。但是,它也使程序的内存占用更大,因为现在必须用函数的完整代码替换每个函数调用。要使事情变得更复杂,请记住,CPU在CPU上的缓存中存储频繁使用的内存块,以便进行超高速访问。如果使程序的内存映像足够大,程序将无法有效地使用缓存,而且在最坏的情况下,内联实际上可能会降低程序的速度。在某种程度上,编译器可以计算出权衡的结果,并且可能能够做出比你所能做的更好的决定,只是看看源代码。

#13


1  

Our computer science professor urged us to never use inline in a c++ program. When asked why, he kindly explained to use that modern compilers should detect when to use inline automatically.

我们的计算机科学教授敦促我们不要在c++程序中使用内联。当被问及原因时,他和蔼地解释说,现代编译器应该检测什么时候自动使用内联。

So yes, the inline can be an optimization technique to be used wherever possible, but apparently this is something that is already done for you whenever it's possible to inline a function anyways.

是的,内联可以是一种优化技术,在任何可能的情况下都可以使用,但显然这是已经为您做过的,无论何时,只要有可能内联一个函数。

#14


-1  

Conclusion from another discussion here:

从另一个讨论的结论:

Are there any drawbacks with inline functions?

内联函数有什么缺点吗?

Apparently, There is nothing wrong with using inline functions.

显然,使用内联函数没有什么错。

But it is worth noting the following points!

但值得注意的是以下几点!

  • Overuse of inlining can actually make programs slower. Depending on a function's size, inlining it can cause the code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs faster due to better use of the instruction cache. - Google Guidelines

    过度使用内联实际上会使程序变慢。根据函数的大小,内联可以使代码大小增加或减少。内联一个非常小的访问函数通常会减少代码大小,而内联一个非常大的函数可以显著增加代码大小。在现代处理器中,由于更好地使用指令缓存,较小的代码通常运行得更快。——谷歌指南

  • The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost - Source

    内联函数的速度优势随着函数的增大而减小。在某些时候,与执行函数体相比,函数调用的开销变得很小,并且好处是丢失了源

  • There are few situations where an inline function may not work:

    有一些情况下,内联函数可能不能工作:

    • For a function returning values; if a return statement exists.
    • 函数返回值;如果存在返回语句。
    • For a function not returning any values; if a loop, switch or goto statement exists.
    • 对于不返回任何值的函数;如果存在循环,则切换或goto语句。
    • If a function is recursive. -Source
    • 如果函数是递归的。源
  • The __inline keyword causes a function to be inlined only if you specify the optimize option. If optimize is specified, whether or not __inline is honored depends on the setting of the inline optimizer option. By default, the inline option is in effect whenever the optimizer is run. If you specify optimize , you must also specify the noinline option if you want the __inline keyword to be ignored. -Source

    __inline关键字只在指定优化选项时才会使函数内联。如果指定了优化,那么是否使用__inline取决于内联优化器选项的设置。默认情况下,无论何时运行优化器,inline选项都是有效的。如果要忽略__inline关键字,则还必须指定noinline选项。源