0

I want to define an inline function in a header file (.h) which can be included by numerous source files (.c). Here is a minimal example with 1 header and 2 source files:

Header file foo.h

int ifunc(int i);

extern inline
int
ifunc(int i)
{
  return i + 1;
}

Source code file: foo.c

#include <stdio.h>
#include "foo.h"

int foo2(int i);

int main()
{
  printf("%d\n", foo2(1));
  return 0;
}

Source code file foo2.c

#include "foo.h"
int foo2(int i)
{
  return ifunc(i);
}

The problem

When I compile with optimization,

gcc -g -Wall -O2 -o foo foo.c foo2.c
$ ./foo
2

everything works fine. However when I turn off optimization, I get this error:

gcc -g -Wall -o foo foo.c foo2.c
/tmp/cc3OrhO9.o: In function `foo2':
foo2.c:5: undefined reference to `ifunc'

Can someone please explain how to fix so that I can run the code with and without -O2? I am using gcc 4.8.5.

vibe
  • 333
  • 1
  • 9
  • Be aware that GCC has a mode for `inline` functions that pre-dates the C standard mode for `inline` functions, and the GCC and standard modes are different. The `extern` might be relevant to GCC's mode; it isn't exactly what's supposed to be used with standard C. Using `static` instead of `extern` is usually the simplest mechanism. You can find more information about `inline` at [Is `inline` without `static` or `extern` ever useful in C99](https://stackoverflow.com/questions/6312597/) and [`extern inline`](https://stackoverflow.com/questions/216510/extern-inline). – Jonathan Leffler Dec 19 '18 at 00:12

1 Answers1

1

if you replace foo.h with

static inline int ifunc(int i)
{
  return i + 1;
}

Both will work. Declaring it extern means it'll be defined somewhere else which in your original example does not happen. And the optimized build doesn't flag as an error because it already optimized it to be inline it but the non-optimized build does not find a definition in any of the .o files (since they were all compiled with ifunc being an extern as defined in foo.h).

Declaring as static inline will ensure that it is local to each file (the downside being that if it does not inline it, you'll end up with each .o that needs it having a local copy, so don't overdo it).

csd
  • 934
  • 5
  • 12
  • More or less — but `extern` has more complex semantics when used with `inline`. See the questions linked to in my comment to the main question. The primary recommendation — use `static inline` in the header — is what I recommend. – Jonathan Leffler Dec 19 '18 at 00:13
  • Thanks this fixed it. Although if a .c file includes the .h *without* calling the inline function, gcc will complain about a static function being defined and not used (with -Wunused-function). Maybe theres no way to make gcc completely happy about this. – vibe Dec 19 '18 at 03:13