调用内联函数时出现未定义引用

69

我在使用GCC 4.8.1编译内联函数时遇到了一个非常奇怪的错误。

我的头文件中定义了两个几乎相同的内联函数(debug.herror.h),它们都在src/include/目录下。它们唯一的区别是输出不同——其中一个在消息前打印了DEBUG:,另一个则打印了%s: error: %s(程序名,错误消息)。当我将这些函数都定义为内联函数并编译调试版本(所以设置了宏DEBUG=1)时,会出现很多未定义引用错误:

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

debug()的定义更改为static inline即可消除错误。但是尽管error()的定义为inline而不是static inline,我从未收到过任何错误。

这些定义都在头文件中(即未进行原型声明)。


6
我发现编译器在使用 -O0 或没有使用 -O 标志时,在引用 inline func(); 时会出现“未定义的引用(undefined reference)”错误,而在使用 -O1-O2-O3 时则可以成功编译。请注意不要改变原文意思,只需让翻译更易懂。 - exebook
1
@exebook 谢谢,那解决了我的问题。这里的答案提供了一个解释:https://dev59.com/W2Qo5IYBdhLWcg3wMs-2。 - nielsen
3个回答

74
根据手册,传递-std=gnu11将启用 C99 而不是 GNU 内联语义。
这意味着inlinestatic inlineextern inline 都有不同的行为。特别是,inline 期望在单独的翻译单元中具有外部定义(您可以提供而不重复定义-请参见此答案)。

1
以上的答案都没有给出确切的解决方案!
使用 "static inline" 来避免未定义或重复定义的错误。"static inline" 在 C++ 中的行为类似于 "inline"。

1

https://en.wikipedia.org/wiki/Inline_function#C99 在 C99 中,定义为内联函数的函数永远不会发出外部可见函数,而定义为 extern inline 的函数总是会发出外部可见函数。与 C++ 不同的是,没有办法要求只在需要时才发出在翻译单元之间共享的外部可见函数。

因此,要解决此错误,只需为此函数添加 extern inline。


1
不,最好添加static inline以追求C++的行为。如果从多个源文件中包含头文件,extern inline将会生成重复的错误。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接