• Uncategorized

About c : undefined-reference-when-calling-inline-function

Question Detail

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:

  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\""

  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

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

  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

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

  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)

Question Answer

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).

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.