You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

inline函数未定义引用问题及C99编译报错求助

解决inline函数编译时的undefined reference问题

让我们一步步拆解你遇到的问题:

问题重现

你的代码如下:

#include <stdio.h>
#include <string.h>
#include <signal.h>
inline void func() { return; }
int main(int argc, char const *argv[]) {
    func();
    sigset_t oldset;
}
  1. 直接用gcc main.c编译时,链接器报错:
main.c:(.text+0x2d): undefined reference to `func'
collect2: error: ld returned 1 exit status
  1. 添加-std=c99参数后又出现新的错误(你提到的error: unknow...,大概率是老版本GCC对C99标准库的兼容问题,后面会顺带解决)

错误原因分析

第一个链接错误的根源

GCC默认使用gnu89(GNU扩展的C89)模式,这个模式下对inline的处理和C99标准不一样:

  • 如果一个函数被声明为inline,但编译器没有选择将其内联(比如某些场景下编译器会放弃内联优化),链接器就需要这个函数的外部定义(非inline版本)。但你的代码里只有inline的定义,没有对应的外部符号,所以链接器找不到func就报错了。

-std=c99后的可能问题

如果是error: unknown type name 'sigset_t',那是因为在严格C99模式下,sigset_t属于POSIX扩展类型,需要提前定义_POSIX_C_SOURCE宏才能让signal.h暴露这个类型。

解决方案

方案1:用static inline替代inline(最推荐)

inline改成static inline后,函数变成内部链接,只在当前文件可见。编译器会确保为它生成必要的定义(如果没内联的话),完全避免链接问题:

#include <stdio.h>
#include <string.h>
#include <signal.h>
static inline void func() { return; }
int main(int argc, char const *argv[]) {
    func();
    sigset_t oldset;
}

编译命令直接用gcc main.c或者gcc main.c -std=c99都可以正常通过。

方案2:遵循C99标准提供外部定义

如果你坚持要用inline,按照C99标准,需要在代码中同时提供该函数的外部声明(让编译器知道存在一个外部定义):

#include <stdio.h>
#include <string.h>
#include <signal.h>

inline void func() { return; }
// 声明外部定义,让链接器能找到符号
void func();

int main(int argc, char const *argv[]) {
    func();
    sigset_t oldset;
}

编译时用gcc main.c -std=c99即可。

顺带解决C99模式下的sigset_t问题

如果加-std=c99后出现sigset_t未定义的错误,只需要在所有头文件之前定义_POSIX_C_SOURCE宏:

#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <string.h>
#include <signal.h>
static inline void func() { return; }
int main(int argc, char const *argv[]) {
    func();
    sigset_t oldset;
}

内容的提问来源于stack exchange,提问作者L.Ward

火山引擎 最新活动