69

I am getting a really odd error from GCC 4.8.1 with inline functions.

I have two near-identical inline functions defined in header files (debug.h and error.h) in src/include/, with the only difference being what they print - one prefixes DEBUG: to the message, and the other %s: error: %s (program name, error message). When defining the functions both inline, and compiling a debug build (so it sets the macro DEBUG=1), I get lots of undefined reference errors:

src/main_debug.o
  gcc -osrc/main_debug.o src/main.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1 -DBTCWATCH_VERSION="\"0.0.1\""

src/lib/btcapi_debug.o
  gcc -osrc/lib/btcapi_debug.o src/lib/btcapi.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1

src/lib/libbtcapi_debug.a
  ar rc src/lib/libbtcapi_debug.a src/lib/btcapi_debug.o
  ranlib src/lib/libbtcapi_debug.a

src/lib/cmdlineutils_debug.o
  gcc -o src/lib/cmdlineutils_debug.o src/lib/cmdlineutils.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1

src/lib/libcmdlineutils_debug.a
  ar rc src/lib/libcmdlineutils_debug.a src/lib/cmdlineutils_debug.o
  ranlib src/lib/libcmdlineutils_debug.a

debug
  gcc -obtcwatch-debug src/main_debug.o -Lsrc/lib/ -lbtcapi_debug -lcmdlineutils_debug -lcurl  -ljansson 
src/main_debug.o: In function `main':
/home/marcoms/btcwatch/src/main.c:148: undefined reference to `debug'
src/main_debug.o:/home/marcoms/btcwatch/src/main.c:185: more undefined references to `debug' follow
collect2: error: ld returned 1 exit status
make: *** [debug] Error 1

But changing debug()'s definition to static inline removes the errors. But I have never received any errors from error()'s definition, although its defenition is inline, and not static inline.

The definitions are all in headers (i.e. not prototyped)

Marco Scannadinari
  • 1,774
  • 2
  • 15
  • 24
  • 6
    I have found that the compiler will result in `undefined reference` on referenceing the `inline func();` with `-O0` or absent `-O` flag, and will compile successfully with `-O1`, `-O2`, `-O3`. – exebook Feb 27 '21 at 07:24
  • 1
    @exebook Thanks, that solved my problem. An explanation is provided in the answers here: https://stackoverflow.com/questions/16245521/c99-inline-function-in-c-file. – nielsen Jul 05 '21 at 12:09

2 Answers2

74

According to the manual, passing -std=gnu11 enables C99 instead of GNU inline semantics.

This means inline, static inline and extern inline all behave differently. In particular, inline expects an external definition in a separate translation unit (which you can provide without duplicating the definition - see this answer).

Community
  • 1
  • 1
Christoph
  • 164,997
  • 36
  • 182
  • 240
0

https://en.wikipedia.org/wiki/Inline_function#C99 In C99, a function defined inline will never, and a function defined extern inline will always, emit an externally visible function. Unlike in C++, there is no way to ask for an externally visible function shared among translation units to be emitted only if required.

So to fix this error, just add extern inline for this function