【环境】

  > KEIL5.25

  > win10

  > @2018-4-23

【问题】

头文件互包含导致的错误(使用了另一文件的类型定义)

文件<fileA.h>

  <fileA.h>

  #ifndef    __FILEA_H__
#define __FILEA_H__ #include "fileB.h" typedef struct
{
int var;
}stuct_A_s; #endif

文件<fileB.h>

 <fileB.h>

 #ifndef    __FILEB_H__
#define __FILEB_H__ #include "fileA.h" typedef struct
{
int var;
struct_A_s obj;
}struct_B_s; #endif

编译后报错:在文件<fileB.h>中   error:  #20: identifier "struct_A_s" is undefined

【分析】

导致上述错误的原因,是在文件<fileA.h>中,使用了 fileB.h,而文件<fileB.h>中使用的类  struct_A_s 在其定义之前,故产生了先使用后定义的语法错误

具体分析:

  从文件<fileA.h>开始分析:

  > 执行避免头文件重复包含的宏 --- <fileA.h>

  > 包含文件<fileB.h>,进入文件<fileB.h>

  > 执行避免头文件重复包含的宏 --- <fileB.h>

  > 包含文件<fileA.h>,进入文件<fileA.h>

  > 由于避免重复包含宏的控制,进不去A文件内容部分,跳转回文件<fileB.h>

  > 执行结构体 struct_B_s 定义,结构体成员类型使用了结构体 struct_A_s ,这就出现了使用了未定义的情况,执行完毕跳转回文件<fileA.h>

  > 执行结构体 struct_A_s 定义,结合上一步就发生了先使用后定义的问题,执行完毕结束

  结论:编译器先从文件<fileA.h>开始编译就会出现本文所示错误

  从文件<fileB.h>开始分析:

  > 执行避免头文件重复包含的宏 --- <fileB.h>

  > 包含文件<fileA.h>,进入文件<fileA.h>

  > 执行避免头文件重复包含的宏 --- <fileA.h>

  > 包含文件<fileB.h>,进入文件<fileB.h>

  > 由于避免重复包含宏的控制,进不去B文件内容部分,跳转回文件<fileA.h>

  > 执行结构体 struct_A_s 定义,执行完毕跳转回文件<fileB.h>

  > 执行结构体 struct_B_s 定义,执行完毕结束

  结论:编译器先从文件<fileB.h>开始编译就不会报错误

【解决】

  # 去除文件<fileA.h>中包含文件<fileB.h>的语句部分,可解决此问题

  # 由于分析推出是编译顺序导致错误的出现,特做了一下一些事做实验:

    > 控制文件 <fileA.h> 与 <fileB.h> 的编译顺序  (做了文件名的更改,即按照字母表顺序修改文件名达到两次编译时两个文件的排序相异)

    > 两次编译的结果都是报相同的错误,error:  #20: identifier "struct_A_s" is undefined

【结论】

  # 综上暂推出,编译器在编译时,每个文件都会单独编译一遍,所以不论文件 <fileA.h> 与 <fileB.h> 的排序,都会出现相同的问题

  # 一般是杜绝文件互相包含的,因为文件包含的意义就是要使用被包含文件的一些定义,互相包含就会出现先使用后定义 的情况发生

  # 了解一些编译原理的知识后,将会得到更权威的解惑,以上只是根据现象分析的结果

一种KEIL中定义过的变量在使用中提示未定义的情况的更多相关文章

  1. 继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类。 (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。 (3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。 (4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。 分析以上程

    继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法.(3)子类中定义的成员变量和父类中定义的 ...

  2. 【Spring Framework】12种spring中定义bean的方法

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

  3. js中定义属性和变量

    //定义数组 var arr = []; //定义对象 var obj = {}; //定义正则表达式 var reg = /../;

  4. 007、Java中定义int型变量

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  5. 解决webkit浏览器中js方法中使用window.event提示未定义的问题

    这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...

  6. VC中明明已经添加了头文件却还提示未定义的问题

    我在VS中编译程序遇到这个错误:error C3861: 'ReadDirectoryChangesW': identifier not found, even with argument-depen ...

  7. strcasecmp在VS2010中提示未定义标识符

    分析: strcasecmp(*,*)是用来比较字符串,定义在string.h头文件中,但是在windows下即使添加string.h头文件,依然会报错. 解决: 添加 #if defined(_MS ...

  8. (转载)JavaScript中定义变量

    (转载)http://blog.163.com/xuxiaoqianhz@126/blog/static/165190577201061594421870/ JavaScript中定义变量有两种方式: ...

  9. MFC 如何在一个类中使用在其他类中定义的变量或函数

    [声明:本文的知识点来源于网络,参考网址:https://blog.csdn.net/bill_ming/article/details/7407848] [以下三种方法亲测有效,可以根据具体情况来选 ...

随机推荐

  1. 人脸识别-关于face_recognition库的安装

    首先十分感谢博客https://blog.csdn.net/scc_722/article/details/80613933,经历过很多尝试(快要醉了),终于看了这篇博客后安装成功. face_rec ...

  2. MUI的踩坑笔记

    最近在做公司项目的手机端实现,稍微记录下遇到的坑 1.在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,mui将该事件封装成了mui.plusReady( ...

  3. docker usage

    docker ps -a 查看物理机上面所有容器信息列表 docker exec -it $docker_id /bin/bash 进入容器以默认帐号 docker exec -it -u root ...

  4. wc命令详解

    基础命令学习目录首页 原文链接:http://www.cnblogs.com/peida/archive/2012/12/18/2822758.html Linux系统中的wc(Word Count) ...

  5. Navicat新建查询,系统找不到指定路径 独家解决办法

    Navicat新建查询系统找不到指定路径,很多人用了网上流行的那些解决办法,还是无法解决.比如: https://jingyan.baidu.com/article/86112f1387a713273 ...

  6. 第十二次ScrumMeeting博客

    第十二次ScrumMeeting博客 本次会议于11月30日(四)22时整在3公寓725房间召开,持续35分钟. 与会人员:刘畅.辛德泰.张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的内容 ...

  7. java内存结构JVM——java内存模型JMM——java对象模型JOM

    JVM内存结构 Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存在,而有些区 ...

  8. 随手记录-linux-添加epel源

    下载各种yum源 https://opsx.alibaba.com/mirror https://blog.csdn.net/harbor1981/article/details/51135623

  9. Apache 工作模式的正确配置

       prefork work event

  10. 请教JDBC中的thin和OCI的区别\

    请教JDBC中的thin和OCI的区别 https://zhidao.baidu.com/question/2267123737573204748.html