Description of problem: An inline function causes undefined symbol error if not static, or -O level given Version-Release number of selected component (if applicable): GCC 7.1.1-3 How reproducible: Reliably reproducible, Steps to Reproduce: Compile the following shortened sample without options __inline__ int doubler(int number) { return number * 2; } int main(int argc, char**argv) { return doubler(argc); } Actual results: $ LC_ALL=C gcc inline-bug.c /tmp/cclHMpkK.o: In function `main': inline-bug.c:(.text+0x15): undefined reference to `doubler' collect2: error: ld returned 1 exit status Expected results: Compilation should succeed w/o messages. Additional info: If any -O option except -O0 is added, the problem disappears. From assembly, it looks like GCC omits the code for the function, but nevertheless emits a call to it.
Your program is not valid. See "Different semantics for inline functions" at https://gcc.gnu.org/gcc-5/porting_to.html
I guess that strange behaviour is permitted by C99, but reading about inline in the latest free draft (http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf) suggests that GCC could also do the right thing, and still be compliant: >>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.<< (from 6.7.4 "semantics"). GCC could always use the inline definition, which apparently is what it does when any optimization is enabled.
When optimization is enabled the function gets inlined, so no definition is needed.
Yes, but then the same very valid-looking code may call an entirely different function, depending on whether optimization is on. Could cause fun situations in debugging. Given this situation, it seems to me an inline without static should cause a warning (in C mode), because it is likely the user did not expect this obscure behaviour. The writers of the code that prompted me to make this bug report certainly didn't.
When using the C99 inline semantics without static, it is expected that exactly one TU provides the extern definition that then can be used whenever some call in that TU or other TU couldn't be inlined. There are many reasons why something isn't inlined, inlining is just an optimization; inlining could not be done because the user asked not to (-fno-inline, default with -O0), or the inline function's address is stored in a function pointer and the optimizers can't track it to all indirect calls through that function pointer, or the inline function contains something that prevents inlining (e.g. alloca), or is too large or the compiler doesn't see it as beneficial. If you want to unconditionally force inlining, GCC provides a way - inline __attribute__((always_inline)). Note, this isn't much different from the old GNU inline semantics, inline is an optimization there too and one needs to provide a fallback if inlining fails.