当前位置:   article > 正文

头文件循环引用导致“unknown type name”的问题详解

unknown type name

问题原因

        最近在做嵌入式项目时,编译过程中头文件爆出了“unknown type name …”的错误。经过检查,未知的变量类型所在的头文件已经被包含在本头文件中了,而且也添加进了头文件目录,通过Ctrl键也能跳转,表面看上去没有任何问题,甚至怀疑是编译器出问题了。随后,我查看了编译过程的输出,通过编译顺序发现了问题所在。

        接下来我描述一下问题具体出现的过程,假如有"a.h" "b.h" "c.h"三个头文件,内容如下:

a.h:

  1. #ifndef _A_H
  2. #define _A_H
  3. #include "c.h"
  4. typedef struct
  5. {
  6. uint8 a;
  7. uint8 b;
  8. }type_a;
  9. u8 num;

b.h:

  1. #ifndef _B_H
  2. #define _B_H
  3. #include "a.h"
  4. typedef struct
  5. {
  6. type_a a;
  7. uint8 b;
  8. }type_b;

c.h:

  1. #ifndef _C_H
  2. #define _C_H
  3. #include "b.h"
  4. typedef struct
  5. {
  6. type_b a;
  7. uint8 b;
  8. }type_c;
  9. typedef char u8;

        当然这只是个很简单的例子,在实际开发中不会出现这样看起来很呆的循环包含的情况。在这个例子中,三个头文件的包含关系是:b包含a,c包含b,而a又包含c。如果编译过程第一个走到c.h, #ifndef _C_H 语句会判断当前没有编译c.h文件,而对c.h进行编译,当执行到 #include "b.h" 这条语句的时候,会寻找名为b.h的头文件并进行编译,而这个时候,c.h中剩下的内容并没有参与编译。同理,在b.h文件中走到 #include "a.h" 这条语句时又会寻找a.h头文件进行编译。而在a.h中,由于包含了c.h头文件,编译器也会去寻找该头文件,然而 #ifndef _C_H 这条语句提示编译器c.h已经参与编译了,因此会跳出c.h的编译,回到a.h中,当继续编译到 u8 num; 时,编译器会发现之前没有编译过名为u8的类型名,最终报出"unknown type name 'u8' "的错误。

        这就是为什么我们包含头文件后明明可以跳转找到类型定义,编译器依旧报"unknown type name"的原因。

解决方案

        其实了解了原因之后,解决方法很明显:

        重新规划头文件内容,调整头文件内容,避免出现循环引用的情况。虽然这一句话看起来很简单,但实际上要对整个项目结构非常了解,熟悉项目涉及的每个头文件的作用。同时调整头文件内容后可能还需要对.c文件也做出相应修改。要是实在不会调整,就只能减少项目功能,精简头文件包含结构了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/39961?site
推荐阅读
相关标签
  

闽ICP备14008679号