Traditionally, the compiler processes every translation unit separately and therefore optimizations such as function inlining are performed for every translation unit separately. In such a setup, it is not possible for function calls to different translation units to be inlined.
However, most modern compilers have a feature called "Whole Program Optimization" or "Link Time Optimization" which is able to perform interprocedural optimization (including inlining) even if both functions reside in different translation units. But in some compilers, this feature is disabled by default and must be explicitly activated in the compiler/linker options.
The inline keyword merely provides a hint to the compiler suggesting that a function be inlined. Whether it is actually inlined or not is for the compiler's optimizer to decide. Many compilers ignore the hint and judge for themselves whether the function should be inlined, based on the size of the function and how often it is called.
However, most compilers will only perform function inlining if compiler optimizations are activated. If not, then even functions declared as inline are unlikely to be inlined.
My goal is to inline the function add both in file1.c and main.c
In order to achieve that goal, I recommend that you either
activate the Whole Program Optimization/Link Time Optimization feature of your compiler described above and hope that the compiler's optimizer takes care of inlining the appropriate functions automatically, or
define the function in both translation units, but make it static inline
, or
define the function as extern inline
in exactly one translation unit (in order to not violate the one definition rule), and simply as inline
(without any 'extern' or 'static' modifier keywords) in all other translation units, making these so-called "inline definitions" pursuant to §6.7.4 ¶7 of the C11 standard, which leaves it up to the compiler whether it takes the external definition or the definition in the same translation unit.
If you use static inline
in all translation units, then you run the risk of unnecessary code duplication in the executable file. In the case of all function calls being inlined by the compiler's optimizer, this code duplication would have occured anyway, so in that case it wouldn't matter. However, in the case of the compiler deciding not to inline the functions, the compiler will generate one function for every translation unit, duplicating code in the executable file. This can likely be prevented by using extern inline
in one file translation unit and simply inline
(see "inline definitions" described above) in all other translation units.
However, functions declared as extern inline
or simply inline
(not static inline
) have the disadvantage that, according to §6.7.4 ¶3 of the C11 standard, they may not use any variables with internal linkage, only variables with external linkage or no linkage (such as local automatic variables or global variables with external linkage). Also, they may not call any functions with internal linkage (functions with the keyword static
), only functions with external linkage.
Because of the mentioned disadvantages of using static inline
, extern inline
and inline
, I recommend that you don't use them at all. Instead, I recommend that you simply make sure that the appropriate optimization settings on your compiler and linker (see above) are set properly and that you let these two programs decide for themselves which functions should be inlined.
Please note that this answer only applies to the language C, not C++, because you tagged the question with "C". The inline
keyword in C++ has a slightly different meaning and you can use extern inline
in all translation units without violating the C++ one definition rule.
static inline int add(add x, int y) {....}
– Hilburninline
keyword, this exception does not apply here, as it only applies to using the keywordinline
without theextern
keyword. – Harquebus