7

Doing cc -std=c99 example.c on the following simplified example.c file:

inline void a()
{
}

int main()
{
   a();

   return 0;
}

gets me:

In function `main':
example.c:(.text+0x7): undefined reference to 'a'
collect2: ld returned 1 exit status

As I understand this has to do with the requirement of C99 standard to demand exactly one more definition for each inline non-static function that is used in cases where the body cannot be inlined? If that is so, I am guessing I could do with static inline instead, but I don't want this to bite me later, so what would be the best course of action here? Obviously, I want to stick to C99 and I want to inline some functions. (Yes, I am aware the compiler usually knows what to inline without being told so, but I have my reasons)

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
  • The `inline` keyword is not what you think it is. It's at best a hint to the compiler that this code may be a candidate for being inlined. At worse, it's ignored. – jer Mar 20 '11 at 16:50
  • Can you compile other files via your cc? Maybe problem in compiler. – Mihran Hovsepyan Mar 20 '11 at 16:53
  • Actually I am using '-Winline' so in my case it won't be ignored. Pardon me for not specifying this, but I didn't think someone would be commenting on what `inline` means in C or reacting to that side of the matters. In most other variations of the above, you are of course absolutely right. @Mihran no, no problem with the compiler. After checking more closely with the C99 specs, I have specified the inline function(s) in question as `static inline` and everything works. I do want to know if I am taking the right steps here though... – Armen Michaeli Mar 20 '11 at 16:55

2 Answers2

6

Probably you wouldn't have that error when you compile with -O2 or so.

Inline function definitions should go in header files and an extern inline declaration should go in one compilation unit. Do

inline void a(void){
 // empty
}

// in just one .c file
#include "the-file.h"
extern inline void a(void);

BTW, declaring a without void is not a prototype.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • ok, that is interesting. how would I proceed if I need the definition of 'a' to use by several translation units? – Armen Michaeli Mar 20 '11 at 17:19
  • @amn, put just the `inline` *definition* in a header file and the `extern inline` declaration in one of the translation units. Beware that you really need a C99 complying compiler for that. Newer gcc e.g would do. – Jens Gustedt Mar 20 '11 at 17:58
  • @JensGustedt I will keep saying this whenever I find someone who claims this, but the source file must contain the definition too. – yyny Sep 26 '16 at 23:22
  • Sorry, I thought that this was obvious. Please see my edit. – Jens Gustedt Sep 27 '16 at 06:23
  • Wouldn't simply `void a(void);` also work in the .c file? – Michael Morris Dec 08 '17 at 04:14
  • @MichaelMorris, yes, it is just a matter of style. I just think that using `extern` explicitly makes it more obvious that this changes things such that `a` becomes an external symbol of the translation unit. – Jens Gustedt Dec 08 '17 at 09:48
  • I can understand that, but the point that I was getting at was that the `inline` was both unnecessary and confusing when used on the external declaration. – Michael Morris Dec 22 '17 at 15:50
0

There's no function prototype, that's all, so the function signature is inferred, and inferred wrong. Add "void a();" to the top of the file, and you're all set.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • yes, that works if 'a' is defined in the same single translation unit (which is the case with the example I have given). As soon as I try to 'share' this inline function however by putting its definition into own header and including this header from two or more translation units, it does not work and I get the 'multiple definition of 'a' error instead... What gives? – Armen Michaeli Mar 20 '11 at 17:16