Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Inline function
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Storage classes of inline functions == <code>static inline</code> has the same effects in all C dialects and C++. It will emit a locally visible (out-of-line copy of the) function if required. Regardless of the storage class, the compiler can ignore the <code>inline</code> qualifier and generate a function call in all C dialects and C++. The effect of the storage class <code>extern</code> when applied or not applied to <code>inline</code> functions differs between the C dialects<ref name="inline-c99-vs-gnu">{{Cite web|url=http://www.greenend.org.uk/rjk/tech/inline.html|title = Inline Functions in C}}</ref> and C++.<ref name="gcc-inline">{{Cite web|url=https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Inline.html|title = Using the GNU Compiler Collection (GCC): Inline}}</ref> === C99 === In C99, a function defined <code>inline</code> will never, and a function defined <code>extern inline</code> will always, emit an externally visible function. Unlike in C++, there is no way to ask for an externally visible function shared among translation units to be emitted only if required. If <code>inline</code> declarations are mixed with <code>extern inline</code> declarations or with unqualified declarations (ie., without <code>inline</code> qualifier or storage class), the translation unit must contain a definition (no matter whether unqualified, <code>inline</code>, or <code>extern inline</code>) and an externally visible function will be emitted for it. A function defined <code>inline</code> requires exactly one function with that name somewhere else in the program which is either defined <code>extern inline</code> or without qualifier. If more than one such definition is provided in the whole program, the linker will complain about duplicate symbols. If, however, it is lacking, the linker does not necessarily complain, because, if all uses could be inlined, it is not needed. But it may complain, since the compiler can always ignore the <code>inline</code> qualifier and generate calls to the function instead, as typically happens if the code is compiled without optimization. (This may be the desired behavior, if the function is supposed to be inlined everywhere by all means, and an error should be generated if it is not.) A convenient way is to define the <code>inline</code> functions in header files and create one .c file per function, containing an <code>extern inline</code> declaration for it and including the respective header file with the definition. It does not matter whether the declaration is before or after the include. To prevent [[unreachable code]] from being added to the final executable if all uses of a function were inlined, it is advised<ref name="gcc-inline"/> to put the object files of all such .c files with a single <code>extern inline</code> function into a [[static library]] file, typically with <code>ar rcs</code>, then link against that library instead of the individual object files. That causes only those object files to be linked that are actually needed, in contrast to linking the object files directly, which causes them to be always included in the executable. However, the library file must be specified after all the other object files on the linker command line, since calls from object files specified after the library file to the functions will not be considered by the linker. Calls from <code>inline</code> functions to other <code>inline</code> functions will be resolved by the linker automatically (the <code>s</code> option in <code>ar rcs</code> ensures this). An alternative solution is to use link time optimization instead of a library. gcc provides the flag <code>-Wl,--gc-sections</code> to omit sections in which all functions are unused. This will be the case for object files containing the code of a single unused <code>extern inline</code> function. However, it also removes any and all other unused sections from all other object files, not just those related to unused <code>extern inline</code> functions. (It may be desired to link functions into the executable that are to be called by the programmer from the debugger rather than by the program itself, eg., for examining the internal state of the program.) With this approach, it is also possible to use a single .c file with all <code>extern inline</code> functions instead of one .c file per function. Then the file has to be compiled with <code>-fdata-sections -ffunction-sections</code>. However, the gcc manual page warns about that, saying "Only use these options when there are significant benefits from doing so." Some recommend an entirely different approach, which is to define functions as <code>static inline</code> instead of <code>inline</code> in header files.<ref name="inline-c99-vs-gnu"/> Then, no unreachable code will be generated. However, this approach has a drawback in the opposite case: Duplicate code will be generated if the function could not be inlined in more than one translation unit. The emitted function code cannot be shared among translation units because it must have different addresses. This is another drawback; taking the address of such a function defined as <code>static inline</code> in a header file will yield different values in different translation units. Therefore, <code>static inline</code> functions should only be used if they are used in only one translation unit, which means that they should only go to the respective .c file, not to a header file. === gnu89 === gnu89 semantics of <code>inline</code> and <code>extern inline</code> are essentially the exact opposite of those in C99,<ref>{{Cite web|url=http://blahg.josefsipek.net/?p=529|title = Josef "Jeff" Sipek Β» GNU inline vs. C99 inline}}</ref> with the exception that gnu89 permits redefinition of an <code>extern inline</code> function as an unqualified function, while C99 <code>inline</code> does not.<ref name="gcc-5-porting">{{Cite web|url=https://gcc.gnu.org/gcc-5/porting_to.html|title = Porting to GCC 5 - GNU Project}}</ref> Thus, gnu89 <code>extern inline</code> without redefinition is like C99 <code>inline</code>, and gnu89 <code>inline</code> is like C99 <code>extern inline</code>; in other words, in gnu89, a function defined <code>inline</code> will always and a function defined <code>extern inline</code> will never emit an externally visible function. The rationale for this is that it matches variables, for which storage will never be reserved if defined as <code>extern</code> and always if defined without. The rationale for C99, in contrast, is that it would be [[principle of least astonishment|astonishing]] if using <code>inline</code> would have a side-effect—to always emit a non-inlined version of the function—that is contrary to what its name suggests. The remarks for C99 about the need to provide exactly one externally visible function instance for inlined functions and about the resulting problem with unreachable code apply mutatis mutandis to gnu89 as well. gcc up to and including version 4.2 used gnu89 <code>inline</code> semantics even when <code>-std=c99</code> was explicitly specified.<ref>{{Cite web|url=https://gcc.gnu.org/ml/gcc-patches/2007-02/msg00119.html|title = Ian Lance Taylor - Clean up extern inline}}</ref> With version 5,<ref name="gcc-5-porting"/> gcc switched from gnu89 to the gnu11 dialect, effectively enabling C99 <code>inline</code> semantics by default. To use gnu89 semantics instead, they have to be enabled explicitly, either with <code>-std=gnu89</code> or, to only affect inlining, <code>-fgnu89-inline</code>, or by adding the <code>gnu_inline</code> attribute to all <code>inline</code> declarations. To ensure C99 semantics, either <code>-std=c99</code>, <code>-std=c11</code>, <code>-std=gnu99</code> or <code>-std=gnu11</code> (without <code>-fgnu89-inline</code>) can be used.<ref name="gcc-inline"/> === C++ === In C++, a function defined <code>inline</code> will, if required, emit a function shared among translation units, typically by putting it into the common section of the object file for which it is needed. The function must have the same definition everywhere, always with the <code>inline</code> qualifier. In C++, <code>extern inline</code> is the same as <code>inline</code>. The rationale for the C++ approach is that it is the most convenient way for the programmer, since no special precautions for elimination of unreachable code must be taken and, like for ordinary functions, it makes no difference whether <code>extern</code> is specified or not. The <code>inline</code> qualifier is automatically added to a function defined as part of a class definition. === armcc === armcc in C90 mode provides <code>extern inline</code> and <code>inline</code> semantics that are the same as in C++: Such definitions will emit a function shared among translation units if required. In C99 mode, <code>extern inline</code> always emits a function, but like in C++, it will be shared among translation units. Thus, the same function can be defined <code>extern inline</code> in different translation units.<ref>{{Cite web|url=http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka15831.html|title=Documentation β Arm Developer}}</ref> This matches the traditional behavior of Unix C compilers<ref>gcc manual page, description of <code>-fno-common</code></ref> for multiple non-<code>extern</code> definitions of uninitialized global variables.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)