gcc编译inline函数报错:未定义的引用

当在GCC中编译inline函数遇到未定义引用错误时,可以尝试开启-O优化,添加非inline原型声明或在声明时使用static关键字。这些方法有助于理解C语言中inline函数的工作原理,并解决编译问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个简单的inline函数

inline void swap(char *x, char *y){char t = *x; *x=*y; *y=t;}

编译的时候报错

gcc --std=c11 -Wall    -c -o permutation.o permutation.c
gcc   permutation.o  -lgmp -o permutation
permutation.o:permutation.c:(.text+0x92):对‘swap’未定义的引用
permutation.o:permutation.c:(.text+0x92):  截断重寻址至相符: R_X86_64_PC32 针对未定义的符号 swap
permutation.o:permutation.c:(.text+0xcb):对‘swap’未定义的引用
permutation.o:permutation.c:(.text+0xcb):  截断重寻址至相符: R_X86_64_PC32 针对未定义的符号 swap
collect2: 错误:ld 返回 1
make: *** [<内置>:permutation] 错误 1

# 编译器版本
$ gcc --version
gcc (GCC) 9.1.0
Copyright © 2019 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。

解决办法

方法1. 开启 -O 优化

gcc -O   -c -o permutation.o permutation.c
gcc   permutation.o  -lgmp -o permutation

方法2. 添加非inline的原型声明

void swap(char *x, char *y);
inline void swap(char *x, char *y){char t = *x; *x=*y; *y=t;}
cc --std=c11 -Wall    -c -o permutation.o permutation.c
gcc   permutation.o  -lgmp -o permutation

方法3. 声明时同时使用static关键字

static inline void swap(char *x, char *y){char t = *x; *x=*y; *y=t;}
$ make permutation
gcc --std=c11 -Wall    -c -o permutation.o permutation.c
gcc   permutation.o  -lgmp -o permutation

原因

生成汇编代码,查看swap函数的情况,做成表格如下
C11 inline 函数编译

总结

一开始出现编译错误的原因是对swap的调用是真的调用(没有转换成内嵌代码),同时还没有输出swap的对应的汇编代码。

C中定义内联函数要同时使用static inline修饰符,这样生成的代码开启优化选项后不输出汇编代码,直接内嵌调用(一般情况);如果添加非inline函数原型,相当于extern inline swap(){...},即使开启优化选项,也会生成相应的汇编代码,只不过本地调用直接内嵌(一般情况)。

C和C++不一样,C++的inline函数自带static属性,而C中的需要显式指定static才行。

完整代码

#include <stdio.h>
#include <string.h>
#define MX 20

// 输出给定子串的全排
void perm_recursive(char *s, int n);

char buf[MX] = "ABCD";
int main(void){
    perm_recursive(buf, strlen(buf));
    return 0;
}

inline void swap(char *x, char *y){char t = *x; *x=*y; *y=t;}

// 全排的递归实现
static void __perm(char *s, int n, int off){
    if (off == n-1){
        printf("%s", s);
        printf("\n");
    }else{
        for (int k = off; k<n; k++){
            swap(s+off, s+k);
            __perm(s, n, off+1);
            swap(s+off, s+k);
        }
    }

}
void perm_recursive(char *s, int n){
    if (n<1) return;
    __perm(s, n, 0);
}

参考链接

gcc 9.2 文档中inline函数 6.45 An Inline Function is As Fast As a Macro

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值