In my experience, there\'s lot of code that explicitly uses inline functions, which comes at a tradeoff:
GCC 9 Binutils 2.33 experiment to show that LTO can inline
For those that are curious if ld inlines across object files or not, here is a quick experiment that confirms that it can:
main.c
int notmain(void);
int main(void) {
return notmain();
}
notmain.c
int notmain(void) {
return 42;
}
Compile with LTO and disassemble:
gcc -O3 -flto -ggdb3 -std=c99 -Wall -Wextra -pedantic -c -o main.o main.c
gcc -O3 -flto -ggdb3 -std=c99 -Wall -Wextra -pedantic -c -o notmain.o notmain.c
gcc -O3 -flto -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out notmain.o main.o
gdb -batch -ex "disassemble/rs main" main.out
Output:
0x0000000000001040 <+0>: b8 2a 00 00 00 mov $0x2a,%eax
0x0000000000001045 <+5>: c3 retq
So yes, no callq, inlined.
Without -flto:
0x0000000000001040 <+0>: f3 0f 1e fa endbr64
0x0000000000001044 <+4>: e9 f7 00 00 00 jmpq 0x1140
So yes, if you are using -flto, you don't need to worry about putting definitions in headers so they can be inlined.
The main downside of having definitions in headers is that they may slow down compilation. For C++ templates, you may also be interested in explicit template instantiation: Explicit template instantiation - when is it used?
Tested in Ubuntu 19.10.