Chinaunix

标题: 关于头文件中的函数定义 [打印本页]

作者: vime000    时间: 2009-11-09 16:19
标题: 关于头文件中的函数定义
有几个疑问:

1.在头文件中定义inline函数是可以的,可为什么不能在头文件中定义普通的函数呢?不是说inline仅仅是
对编译器的建议吗?如果被编译器忽略了呢,那不跟普通函数一样了吗?

2.在头文件声明函数,cpp文件中定义函数很好理解,在头文件中定义类也很好理解。至于在头文件中定义
函数,为什么会有这种需求呢?我代码写得少,读的少,想不清楚。

3.这些问题的答案,也就是说这样的用法到底合不合法,肯定基于一个准则吧,这个准则是什么呢?哪本书
或资料里有介绍呢?希望从根本上得到个解释~
作者: churchmice    时间: 2009-11-09 17:55
1.你想在头文件中定义普通函数也可以,没人拦着你
至于inline函数,因为在编译的过程中就要进行“替换”,所以你必须要定义在头文件中并且也要include,不然编译器怎么知道这个inline函数是啥?当然你直接把这个inline函数实现的.c给include了也可以。至于普通的函数,是在链接过程中resolve的,所以不存在这个问题,在头文件中只需要有declaration就可以了。没有declaration的话c也是可以,但是很危险,因为这样的话编译器就不能帮你做函数类型检查了(比如说形参个数,返回类型),而且对于没有声明过的函数,gcc会帮你implicit推断出一个返回值为int的函数,这在有些情况下是相当危险的。这部分你可以去看看函数的argument passing以及调用的过程。
一句话,你需要理解编译和链接这两个过程都干了点什么?
比较好的著作你去看看hacking helloworld,一个台湾人写的文章
作者: shan_ghost    时间: 2009-11-09 18:05
先回答这个问题吧:
3.这些问题的答案,也就是说这样的用法到底合不合法,肯定基于一个准则吧,这个准则是什么呢?哪本书
或资料里有介绍呢?希望从根本上得到个解释~


首先要知道如下两点:

1、扩展名不提供任何功能。

所以,技术上根本不需要区分何谓头文件、何谓实现文件。

所谓include,其实就是指示编译器,让它把指定文件的内容拷贝过来,把 #include 那一行给覆盖了。

所以,可以认为,最终给编译器看到的东西里面,include是不存在的,只有单纯的函数原型声明,可能还有部分或者全部这些函数的实现。

这样一份已经被整合过的文件,就叫做一个编译单元。它最终对应一个.o文件(windows下是.obj)。


下一步就可以用链接器把所有这些编译单元、静态库以及动态库统统链接起来,形成可执行文件或者库。



2、如上,想象一下,如果一个很大的项目,没有规矩,谁想包含谁都可以,这样东拉西扯下来会出现什么?

显然,首先是程序不敢改了。一改别人的文件也跟着变,这哪受得了。

其次,程序很难编译成功。因为这个.o文件里有函数A的实现,那个.o文件里也有函数A的实现,链接器哭了:我究竟该以谁为准啊。
最糟糕的时候,还可能出现循环依赖,甚至是包含关系死循环。

所以,程序界哪些聪明的先行者们就约定,大家都把文件分两种,一种叫头文件,只声明接口,不准写实现代码,这样只要接口名字不冲突头文件就可以随便包含;另一种叫实现文件,实现文件里就随便搞了;但必须注意,任何人都不准包含实现文件——否则链接器就又要哭了。




了解了以上基础,你的这些问题就很好回答了:

1.在头文件中定义inline函数是可以的,可为什么不能在头文件中定义普通的函数呢?不是说inline仅仅是
对编译器的建议吗?如果被编译器忽略了呢,那不跟普通函数一样了吗?


inline的含义本身,就是“让编译器把删掉了call/return过程的实现代码弄得到处都是”,但如果编译器无法inline,那么它就还原成函数调用。

比如,一个虚函数能不能inline?为什么?



2.在头文件声明函数,cpp文件中定义函数很好理解,在头文件中定义类也很好理解。至于在头文件中定义
函数,为什么会有这种需求呢?我代码写得少,读的少,想不清楚。


没有在头文件里定义函数的需求。原因如上所述。

注意一个特殊情况: STL相当于一种智能宏,它会根据参数自动生成代码。
但没有模板参数怎么办?

所以,STL实现不能当作独立的编译单元,它必须被其他.c文件包含、并提供模板参数之后、才有可能得到真正的实现代码。

所以,严格的说,STL的实现其实也是一种声明。这里面的技术细节更多,不过我们这些不写通用库的人就不需要追究了。

[ 本帖最后由 shan_ghost 于 2009-11-9 18:06 编辑 ]
作者: vime000    时间: 2009-11-09 20:18
恩,讲解的比较详细,谢谢两位~


作者: dhb118    时间: 2009-11-10 11:15
3楼 是老师吧 回答的思路井井有条 让人看了很容易接受.
论坛能有您在 菜鸟们真有福气啊.:wink:




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2