开发者

What's the inline here for?

开发者 https://www.devze.com 2023-01-26 22:14 出处:网络
What\'s the difference between the 2 definitions below:开发者_运维知识库 #define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \\

What's the difference between the 2 definitions below:开发者_运维知识库

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \
inline Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \
Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \


The word "inline" signals to some compilers that the function should be inlined if possible, i.e. the code from the function's body should be "copy pasted" into the call site, rather than generated as a stand-alone function.

This can save time, since if the work being done is smaller than the work in doing the call itself, it's a net win to remove it. It can also slow things down, by bloating the code and killing the cache.


Since to my taste all the answers, even the accepted one, get the main aspect of inline wrong and in particular in what it means for the use in macros, I try another one.

The inline keyword determines if a function definition (not declaration) will result in the generation of the function in the current compilation unit. There are basically 3 cases:

  • If you just put a "plain" definition the function must be generated and an external symbol for that function is inserted.
  • For an inline definition a function may be generated and if so this may or may not insert an external symbol to the object.
  • For a static definition a function may be generated (usually if it is used) but the name will never be an external symbol.

For the first, if two compilation units define the same function there will be an error when linking the two object files together in one executable.

For the later, if two compilation units define the same function both object files will contain copies of the function that will not be merged when they are linked.

With respect to the macros that are presented in the question this makes an important functional difference. The first, inline, can be expanded anywhere especially in a header file without causing conflicts. The second can only be use in a .c file and in addition no two such .c should do that if they should end up in the same executable.


Edit: w.r.t to Charles' comment. inline functions may well be also external symbols. The rules for that are a bit complex, see the corresponding paragraph 6.7.4 from C99 below. Basically there are three cases that will work if you have several translation units that will be linked together

  1. declare and define the function extern inline in a .h file and declare it again just inline without extern in exactly one .c file.
  2. declare and define the function inline in a .h file and redeclare it without inline in exactly one .c file. This is in fact similar to the instantiation of template functions in C++.
  3. declare and define the function inline in a .h file and redeclare it extern inline in exactly one .c file.

Before version 4.3, gcc had a different model for this type of instantiation of inline functions that is incompatible with this normative one. See also this page for a good read on this subject.

Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.


The difference is that in first case no function invokation is happening. The function is 'inlined', which means the calling is replaced with method body. It helps to optimize the execution as no context have to be saved before the invokation and restored afterwards.


It is a keyword that was valid mainly when compilers were not good enough to determine for themselves whether or not it is preferrable to inline. Todays modern compilers are often a lot better at determining this, using link-time code generation if necessary (whole-program analysis).


The "inline" keyword is used to indicate to the compiler that you would like it to perform inline expansion of the function, or in other words expand the function in place of the call.

A few points to make

  1. The reason this is usually done is to save the overhead of calling another function
  2. the "inline" keyword is only a request to the compiler and the compiler can decide whether to honour it or not
  3. Inlining can have unintended consequences so should be used with caution
  4. Compiler todays usually do a better job of deciding which functions should be inlined for you and will do that automatically if the appropriate arguments are provided to your compiler


I noted in comments to unwind's answer that you wanted to know the following:

If a function can't be inlined, and was marked so you will get a warning if you pass -Winline to GCC.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号