【问题标题】:C Unknown type name 'my_structure'C 未知类型名称'my_structure'
【发布时间】:2013-09-25 01:07:18
【问题描述】:

我有这个代码:

main.h

#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif

my_struct.h

#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
    int a;
} my_structure;
...
#endif

但是当我尝试编译时我得到了这个:error: unknown type name ‘my_structure’

知道为什么吗?

【问题讨论】:

    标签: c gcc struct


    【解决方案1】:

    错误消息来自main.h,而它包含在my_struct.h 中,在my_structure 定义之前。您应该重新考虑您的包含路径,因为 main.hmy_struct.h 相互包含。

    您可能希望您的main.h 文件只包含my_struct.h,而不是让my_struct.h 包含任何内容。您实际上是在指示您的 C 编译器有一个无限的共同包含循环。

    【讨论】:

    • 但是MAINH 不应该保护我免受这种伤害吗?
    • 它会保护您免于包含它两次,但当我相信您打算反其道而行之时,您仍然会包含 main.hmy_struct.h
    • @alexandernst 您应该将包含放在 ifndef 指令之外,以按预期工作
    • @alexandernst:它确实保护您免受无限包容。但是你得到的错误是这种“保护”的直接后果。
    【解决方案2】:

    您创建了一个循环标题包含。循环包容从来没有取得任何成就。它是无限的。 #ifndef 包含守卫将在某个不可预测的点打破无限包含圈(取决于哪个标头首先包含在 .c 文件中)。这就是你的情况。基本上,您的循环包含已“解决”为首先包含main.h,其次包含my_struct.h。这就是为什么main.hmy_struct 类型一无所知。

    同样,循环包含永远不会取得任何成果。摆脱循环包含。分层设计标题结构:较低级别的标题包含在较高级别的标题中,但绝不会反过来。在您的情况下,my_struct.h 可能是一个较低级别的标头,这意味着您必须停止将main.h 包含到my_struct.h 中。重新设计您的标题,使my_struct.h 不再需要main.h

    【讨论】:

    • “在某些不可预测的点打破 [...] 包含圈”:感谢您提供的详细信息。正是我想了解的部分。
    【解决方案3】:

    由于您对包含项的排序方式,编译器在看到typedef struct abcd { int a; } my_structure; 之前先看到void some_func(my_structure *x);

    让我们来看看吧。

    假设首先处理my_struct.h,我们得到以下事件序列:

    1. UTILSH 已定义
    2. MAINH 已定义
    3. 因为UTILSH已经定义好了,我们不再处理my_struct.h,所以typedef没有被处理
    4. void some_func(my_structure *x); 正在处理中。
    5. 现在处理typedef

    所以在预处理之后,您的编译器会看到以下声明序列:

    ...
    void some_func(my_structure *x);
    ...
    typedef struct abcd {...} my_structure;
    

    坏juju。您要么需要在main.h 中前向声明my_structure,要么需要打破这种循环依赖(这是首选选项)。 main.h 中是否有任何 my_structure.h 实际使用的内容?如果是这样,您需要将其分解到一个单独的文件中,main.hmy_structure.h 都包含。

    【讨论】:

    • 是的,main.h 包含了我的应用所需的一切。我想我可以重构/清理我的代码。我只是不确定是不是因为这个
    猜你喜欢
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    相关资源
    最近更新 更多