关于inline函数声明和定义为什么不可以分离

简介: 关于inline函数声明和定义为什么不可以分离

个人主页:Lei宝啊

愿所有美好如期而遇


前言

inline函数在使用时声明和定义不可以分离,接下来我们将会解释为什么是这样的。


我们从程序的编译链接说起。

首先我们先介绍一下程序的翻译环境:

编译分以下几个步骤,预处理,编译,汇编,接下来我将会使用Linux来演示。

预处理展开了头文件,去掉了注释,以及宏替换

编译阶段将代码翻译成了汇编指令。

汇编阶段将代码翻译成了二进制指令

以及最后的链接阶段。

上面我们简单了解了一下编译和链接,下面就深入了解一下。

在test.o和可执行程序的代码里,在我们看来都是乱码,没有任何规律,我们也看不懂,但是我们又想知道里面到底汇总了什么,所以我们使用readelf工具来一探究竟。


下面是符号表,可以看到我们代码中的符号汇总在了这个表中,并且没有局部变量。

但是什么是符号?什么是符号汇总?在编译阶段,会进行符号汇总,就是全局上的一些函数,库函数,全局变量等,在汇编阶段,将这些符号的信息编入一个表,就叫做符号表。

值得说明的是函数声明时,函数的符号也会编入符号表,只是没有有效地址,C++规定,写了声明,定义没写或者在其他文件里,然后去调用这个函数,只要参数匹配,暂时不会报错,等到链接的时候,符号表合并,这个时候再找不到函数的有效地址才会报错。

链接阶段,编译器会去符号表中寻找函数的地址,如果找不到就会报错。


了解了这些基本知识后,我们可以介绍inline声明和定义不能分离的原理了。

如果我们inline函数声明与定义分离,像这样:

那么在编译后,inline函数展开,形成的地址不会进入符号表,但是头文件里函数的声明会将Add函数汇总合并到符号表里,因为只是声明,没有有效地址,当编译器真的根据这个无效地址去找函数的定义时,就报错了。

这就是为什么inline函数声明和定义不可以分离。

目录
相关文章
|
NoSQL 安全 Linux
C++ | 对比inline内联函数和宏的不同点-1
C++ | 对比inline内联函数和宏的不同点
90 1
|
2月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
2月前
|
编译器 C语言 C++
什么是函数声明和定义
【10月更文挑战第19天】什么是函数声明和定义
78 0
|
7月前
|
存储 程序员 Shell
【C/C++ 基本语法 结构体】C++ 结构体声明(定义)以及不同写法的差异
【C/C++ 基本语法 结构体】C++ 结构体声明(定义)以及不同写法的差异
117 1
|
7月前
|
安全 编译器 数据库
C++特性——inline内联函数
C++特性——inline内联函数
|
编译器 Android开发 C语言
C++ | 对比inline内联函数和宏的不同点-2
C++ | 对比inline内联函数和宏的不同点
80 1
|
7月前
|
C++
C++基础-命名空间-缺省参数-函数重载-引用-内联-auto-范围for(1)
1. 命名空间 在C/C++中,变量、函数和类都是大量存在的,它们的名称都将存在于全局作用域中,可能会导致很多冲突。如下图:
61 0
|
存储 安全 编译器
02-📝C++核心语法|C++对C的扩展【::作用域运算符、名字控制、struct类型加强、C/C++中的const、引用(reference)、函数】
复习`C++核心语法`,且适当进行汇编探索底层实现原理,进一步夯实基础,为以后的`底层开发`、`音视频开发`、`跨平台开发`、`算法`等方向的进一步学习埋下伏笔。
02-📝C++核心语法|C++对C的扩展【::作用域运算符、名字控制、struct类型加强、C/C++中的const、引用(reference)、函数】
|
存储 安全 编译器
c++关键字,命名空间,缺省参数,函数重载,引用,内联函数auto等学习(下)
c++关键字,命名空间,缺省参数,函数重载,引用,内联函数auto等学习(下)
116 0