1

I have the following simple C program.

#include <stdio.h>

INLINE void print(const char *s) {
    printf("%s\n", s);
}

int main() {
    print("Hello World!");
    return 0;
}

But I got the following error if I define INLINE as inline. I don't understand the first run fails. My understanding is that the print() function should be inlined in main() at the compile time, so there should not be a link error complaining about the undefined reference to print. Could anybody help me understand why inlining would make it not working? clang also gives a similar error. Thanks.

$ gcc -DINLINE=inline -o main.exe main.c
/tmp/mktemp/ccSbK5B8.o: In function `main':
main.c:(.text+0xc): undefined reference to `print'
collect2: error: ld returned 1 exit status
$ gcc -DINLINE= -o main.exe main.c

EDIT: But with -O2 the keyword static is not required. why?

user1424739
  • 11,937
  • 17
  • 63
  • 152
  • 1
    Possible duplicate of [C99 referring to inline function: undefined reference to XXX and why should I put it to header?](https://stackoverflow.com/questions/18635665/c99-referring-to-inline-function-undefined-reference-to-xxx-and-why-should-i-pu). The tl;dr is you need `static inline`. – Schwern Feb 25 '19 at 22:18
  • it is not the dupe as inline does not work without the optimisation enabled. with -O0 you will get this error. – 0___________ Feb 25 '19 at 22:27
  • 3
    @P__J__ of course it is the dupe. – Antti Haapala -- Слава Україні Feb 25 '19 at 22:29
  • @P__J__ I'm inclined to think it *should* be considered a dupe. Sure `-O1` might fix the error, and you can add that as an answer to the other questions, but I think code should preferably be made to work at all optimization levels. – Petr Skocik Feb 25 '19 at 22:32
  • @PSkocik it is very common trap :). inline and -O0 :). inline functions do not generste linkable code, and the code itself do not inline functions :) and we have undefined reference – 0___________ Feb 25 '19 at 22:34
  • @P__J__ but this is about not understanding the `inline` keyword at all. – Antti Haapala -- Слава Україні Feb 25 '19 at 22:35
  • @AnttiHaapala I do not understand what you mean – 0___________ Feb 25 '19 at 22:35
  • @P__J__ `inline` is still a hint. Linking can fail with even `-O42` if the compiler thinks it is not worth inlining the function – Antti Haapala -- Слава Україні Feb 25 '19 at 22:37
  • from gcc documentation: `Inlining of functions is an optimization and it really “works” only in optimizing compilation. If you don't use -O, no function is really inline.` BTW to make sure that the function will be 100% inlined you need to use __attribute__((always_inline)) – 0___________ Feb 25 '19 at 22:37
  • @AnttiHaapala no - if the inline function with the optimisation will not be inlined it will generate the linkable object code - test it yourself. At least gcc as do not use other compilers – 0___________ Feb 25 '19 at 22:38
  • @P__J__ [it doesn't, this is not how C works](http://port70.net/~nsz/c/c11/n1570.html#6.7.4p10). IIRC it was changed too... – Antti Haapala -- Слава Україні Feb 25 '19 at 22:40
  • @P__J__ afaik, https://gcc.gnu.org/onlinedocs/gcc/Inline.html - depends on mode. With gnu11, gcc should adhere to standard semantics. – Antti Haapala -- Слава Україні Feb 25 '19 at 22:42
  • 1
    @P__J__, it has nothing in particular to do with optimization. An inline declaration of a function with external linkage *requires* an external definition of that function somewhere in in the program if that function is ever called. If all of the declarations of a given function in a given translation unit specify `inline` but not `extern`, then that translation unit does not provide the required external definition. That some compilers may nevertheless produce an executable from such code under some circumstances does not make that code even conditionally correct. – John Bollinger Feb 25 '19 at 22:45

0 Answers0