• 欢迎访问我的博客,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站
  • 本网站关闭了评论功能,联系请点击→邮箱
  • Ctrl+D 可快捷收藏本站点

预处理–文件包含(#include)可能引发的编译错误

C/C++ gql 4年前 (2021-04-23) 1160次浏览

#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后认为该文件定义了这个宏。


如未注明 , 均为原创。转载请注明原文链接:预处理–文件包含(#include)可能引发的编译错误
喜欢 (0)