77

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)

2
  • 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. Commented Feb 27, 2021 at 7:24
  • 1
    @exebook Thanks, that solved my problem. An explanation is provided in the answers here: stackoverflow.com/questions/16245521/…. Commented Jul 5, 2021 at 12:09

3 Answers 3

83

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

Sign up to request clarification or add additional context in comments.

Comments

12

None of the above answers had given exact working solution!

Use static inline to avoid undefined or duplicate definition errors. static inline will behave like inline in C++.

Comments

1

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

1 Comment

No, it's better to add static inline to pursue C++ behavior. extern inline will generate duplicate errors if header is included from multiple sources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.