【】关于C/C++ 的源文件(.cpp)为什么要包含自己的头文件(.h)的思考
- 目的:为了让编译器检验声明与定义(函数体)的一致性(尽可能让编译器帮我们发现错误)
我自己的理解:
- 1、编译器是以文件为单位进行编译(同时进行编译检查)的
- 2、对编译后的文件进行链接时,可能是以函数名(指针)来判断是否存在函数定义(实体)。
如果源文件不包含自己的头文件
会出现什么后果?(如果函数声明和函数定义(体)不一致,这个错误会被编译器发现吗?)
- 首先,编译的时候,由于编译器按文件为单位进行编译,所以这一步编译器不会发现错误。
- 编译器对编译后的文件链接的时候:
--------------如果函数声明和定义的不一致体现在函数名上,那么链接的时候可以检查出来,因为编译生成的函数指针(貌似编译器会根据函数名生成函数指针)都不一样,会报那种没有函数体的错误。
--------------如果函数声明和定义的不一致体现在函数返回值或者函数参数上,那你就糟了,链接也无法检查出错误,编译器会以为他已经找到了函数体,链接完成。
但是当你执行exe文件时,可能就会发生错误,还难以检查。比如,你在 main.cpp 中包含 swap.h 中声明是这样的 int swap(int& a, int& b)
,而你在swap.cpp中的实际定义是 void swap(int& a, int& b)
或者是 void swap(int& a, int& b,int& c)
,使用 g++ .\main.cpp .\swap.cpp
编译链接可以通过并生成 exe 文件,但是执行 exe 显然很可能会发生什么错误。
如果源文件包含自己的头文件
,他们在一个文件中,在不使用函数参数一致的情况下,如果返回值你写的不一致,你在写代码的时候,编译器就会提醒你出声明与定义不一致。
如果函数参数也不一致,比如swap.h中是void swap(int& a, int& b),而swap.cpp 中是void(int& a, int& b, int& c),就算你swap.cpp 中包含 swap.h ,那么编译器也似乎彻底无能为力了(我猜测:有的编译器可能在链接的时候能够报出错误,这可能取决于编译器怎么处理函数,过于深入,我且止步于此),只能在执行的时候发现错误了…