C++'s “inline” - how strong a hint is it for G

2020-02-12 01:13发布

问题:

In C++, the keyword "inline" serves two purposes. First, it allows a definition to appear in multiple translation units. Second, it's a hint to the compiler that a function should be inlined in the compiled code.

My question: in code generated by GCC and Clang/LLVM, does the keyword "inline" have any bearing on whether a function is inlined? If yes, in what situations? Or is the hint completely ignored? Note this is a not a language question, it is a compiler-specific question.

回答1:

[Caveat: not a C++/GCC guru] You'll want to read up on inline here.

Also, this, for GCC/C99.

The extent to which suggestions made by using the inline function specifier are effective (C99 6.7.4).

  • GCC will not inline any functions if the -fno-inline option is used or if -O0 is used. Otherwise, GCC may still be unable to inline a function for many reasons; the -Winline option may be used to determine if a function has not been inlined and why not.

So it appears that unless your compiler settings (like -fno-inline or -O0) are used, the compiler takes the hint. I can't comment on Clang/LLVM (or GCC really).'

I recommend using -Winline if this isn't a code-golf question and you need to know what's going on.



回答2:

An interesting explanation from gcc: An Inline Function is As Fast As a Macro:

Some calls cannot be integrated for various reasons (in particular, calls that precede the function's definition cannot be integrated, and neither can recursive calls within the definition). If there is a nonintegrated call, then the function is compiled to assembler code as usual. The function must also be compiled as usual if the program refers to its address, because that can't be inlined.

Note that certain usages in a function definition can make it unsuitable for inline substitution. Among these usages are: use of varargs, use of alloca, use of variable sized data types (see Variable Length), use of computed goto (see Labels as Values), use of nonlocal goto, and nested functions (see Nested Functions). Using -Winline will warn when a function marked inline could not be substituted, and will give the reason for the failure.

As required by ISO C++, GCC considers member functions defined within the body of a class to be marked inline even if they are not explicitly declared with the inline keyword. You can override this with -fno-default-inline; see Options Controlling C++ Dialect.

GCC does not inline any functions when not optimizing unless you specify the `always_inline' attribute for the function, like this:

 /* Prototype.  */
 inline void foo (const char) __attribute__((always_inline)); The remainder of this section is specific

to GNU C90 inlining.

When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.

If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.

This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file will cause most calls to the function to be inlined. If any uses of the function remain, they will refer to the single copy in the library.



回答3:

How strong the hint is depends entirely on the compile options you use. Most compilers have options to do no inlining, only inline those marked 'inline', or use its best judgement and ignore the hints.

The last one probably works best. :-)