C inline

C inline:不同标准产生的问题

C语言中,在多个.c文件中调用其他文件中的inline函数时,使用默认(不加任何option)、-std=gnu89、-std=gnu99(严格按照C99标准)的编译选项,是否对inline进行声明,会产生不同的编译结果(gcc5.4.0)。

fun.c
#include<stdio.h>
#include"inline_func.h"
//int inline_func(int a);

int foo(void);  
int main()  
{  
    int a = foo();  
    a = inline_func(a);  
    printf("a = %d", a);  
    return 0;  
}  
foo.c
#include"inline_func.h"

int foo(void)  
{  
    int x = 5;  
    x = inline_func(x);  
    return x;  
}  
inline_func.h
#ifndef INLINE_FUNC_H_INCLUDED  
#define INLINE_FUNC_H_INCLUDED  
// static   int inline_func(int a);

inline int inline_func(int a)  
{  
    return a + 1;  
}  
  
#endif // INLINE_FUNC_H_INCLUDED  

而对inline函数的定义是否进行声明,在不同的编译条件下也会产生不同编译结果。究其原因,是各种不同C标准的编译器对inline、extern的不同解释规范。

主要有以下几种情况:

1.单个.c文件中,包含inline函数,而不声明其函数原型,使用C89标准编译正常,而使用C99及默认,则出现"undefined reference"编译错误。说明现代gcc编译器默认对inline函数需要进行声明,而普通的函数则没有该硬性要求。所以,为什么?

2.由于上一条规则的原因,若将inline函数放到.h文件中,在多个.c文件中包含此.h文件,如果在.h文件中未声明其inline函数,使用C89标准编译出现"multiple definition"错误,而使用C99及默认,则出现"undefined reference"编译错误。

而如果在其.h文件中声明其inline函数,则均出现"multiple definition"错误。

3.但是,如果声明时加上inline关键字(默认不加),C99编译结果是"undefined reference",好像是不把带inline的声明视为正确的声明,而C89编译结果则是"multiple definition",好像是将其认作正确的声明。

4.更为神奇的是,不声明而在inline函数的定义处加上extern关键字,C99编译"multiple definition",而C89编译通过!

总结来说,

对于C89编译,只要满足4.中的条件,编译就能通过;

而对于C99编译,必须进行声明,要么是带extern的声明,要么是不带inline关键字的声明(C99视为错误的声明),但是声明的结果就是出现"multiple definition",而不声明又会出现"undefined reference",测试发现在多个.c文件中,只声明一次编译通过,而这个声明放到哪个.c文件中都不合适,怎么解决?

查阅资料发现,将inline函数的定义加上static关键字,C89,C99编译均能通过。

如何避免这些问题?

1.在头文件中声明函数,在.c文件中定义函数

2.使用其他文件中的函数时,包含对应头文件

3.为了避免"multiple definition",多个.c文件使用的inline函数,定义为static inline

关于何时内联

在对以上几种情况下,对通过编译的可执行文件进行反汇编,发现inline函数在其调用处,并未内联,而是均使用了callq进行调用,这点很是奇怪,还请大家指点。

参考资料:

gcc 编译器对 inline 函数的支持

关于 inline 函数的分析: *** undefined reference to ***

C语言inline详细讲解

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值