#include,它可以将一个文件的全部内容拷贝另一个文件中。那如果这个包含的文件出错,可能报错的就不在这个文件中。
这里有一个CMainApp.cpp文件,他包含了三个头文件,分别是CMainApp.h,aaa.h,CMcuFlash.h。
#include "CMainApp.h" #include "aaa.h" #include "CMcuFlash.h"
在aaa.h文件里面也很简单,就是定义了一个类
class AAA { }
那么这个时候编译一下,gcc报错
In file included from src/App/CMainApp.cpp:13:0: src/driver/OnChip/CMcuFlash.h:35:9: error: '#pragma' is not allowed here src/driver/OnChip/CMcuFlash.h:36:16: error: expected declaration before end of line
这里我们看到,在CMainApp.cpp处理第13行包含文件的时候出错,错误的是CMcuFlash.h在第35行#pragma不允许放在这里。
这里打开查看CMcuFlash.h文件,发现文件头定义如下,并没有发现#pragma
#ifndef __CMCUFLASH_H #define __CMCUFLASH_H #include "lib.h" #include "sys_config.h"
继续打开CMcuFlash.h所包含的lib.h文件,这个时候就发现顶部的预处理指令
#pragma once
那么为什么gcc会报错在CMcuFlash.h呢?不知道读者有没有注意到,定义class AAA的时候,最后没有分号。应该修改如下
class AAA { };
在原来的没有分号的时候,CMainApp.cpp使用#include把aaa.h,CMcuFlash.h全部复制到CMainApp.cpp中,CMcuFlash.h还会把lib.h复制进去,编译预处理之后CMainApp.cpp文件如下
class AAA { } #pragma once
显然这是不对的,gcc这一段的错误来自CMcuFlash.h。
所以当编译时,特别是新增了一个文件进行编译,发现之前没有问题的文件却出现了一些莫名的问题,比如CMcuFlash.h没有编译是没问题的,且这个文件里面没有#pragma,那么可以就是之前包含的文件出现问题了。特别是出现
- 最后的括号未补齐。
- 结尾的;未补齐。
- 使用了#if,#ifdef,#ifndef等条件编译未添加#endif
值得注意的是,包含的文件正常的情况下应当早于,条件编译的语句,例如在aaa.h定义一个#define TEST,
#ifndef TEST #error "Not define TEST" #else #error "define TEST" #endif #include "aaa.h" #ifndef TEST #error "Not define TEST" #else #error "define TEST" #endif
这个时候gcc打印信息可以看到
src/App/CMainApp.cpp:23:6: error: #error "Not define TEST" src/App/CMainApp.cpp:33:6: error: #error "define TEST"
这就是因为前面进行预编译这个时候还未包含aaa.h(复制内容)进来,就没有TEST这个宏,后边包含aaa.h后认为该文件定义了这个宏。