1

我有一种情况,我的两个头文件需要任何一个中定义的数据结构,即无论您以哪种顺序包含它们,它都不会编译

然而,有问题的数据结构之一只包含指向另一个头文件中声明的数据结构的指针,所以我会认为,从技术上讲,它现在不需要知道数据结构有多大,所以它不应该是抱怨

下面概述了我的意思的简化示例。我会认为库中的模式数组不需要知道模式有多大,只需要知道模式的指针有多大,因此如果编译器还没有看到模式的声明,它不应该抱怨在另一个头文件中。

header_1.h

typedef struct
{
    Mode **modes; 
} Library;

header_2.h

typedef struct
{
    int number;
    char *name;
} Mode;
4

3 回答 3

3

它不需要知道大小,但它必须看到一个声明。前向声明

typedef struct Mode Mode;

在定义struct Library足够之前。

于 2012-07-09T13:38:30.750 回答
2

如当前所写,您的示例未显示您在问题中提到的相互交叉引用。

必须告诉编译器它使用的每种类型。您可以header_1.h只使用:

typedef struct Mode Mode;

typedef struct
{
    Mode **modes; 
} Library;

至少,这将使它编译。编译器不需要详细信息,但它确实需要知道这Modes是一种类型。

编辑: 请注意,header_2.h应该对其进行修改以使其正常工作。您必须确保每个typedef都只出现一次。设置好 typedef 后,只需指定结构内容(定义)一次,然后从结构定义中省略关键字typedef和 typedef 名称。您必须准确地决定要管理的交叉引用。例如,无论如何都应该header_1.h包括在内。header_2.h

我不记得遇到过我真的需要相互引用结构的情况(在相当长的编程时间里——长到我可能忘记了一个例子)。 我现在确实记得一个结构相互引用的例子。它是make最初为 Minix 编写的版本。我仍然认为这样的要求有点“病态”(或者,如果您愿意,可以说是“代码气味”)并且尽可能避免。如果您真的必须管理它,那么下面的部分将解释我将如何去做(以及或多或少的make程序是如何去做的)。

相互引用的结构

如果你真的有两个相互引用的结构,你应该(重新)考虑为什么你认为两个标题比一个好。如果您仍然需要两个标头,请使用以下成语:

header_1.h

#ifndef HEADER_1_H_INCLUDED
#define HEADER_1_H_INCLUDED

#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif

struct Library
{
    ...
    Mode    **modes;
    ...
};

#endif /* HEADER_1_H_INCLUDED */

header_2.h

#ifndef HEADER_2_H_INCLUDED
#define HEADER_2_H_INCLUDED

#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif

struct Mode
{
    ...
    Library    **liblist;
    ...
};

#endif /* HEADER_2_H_INCLUDED */

重复typedef的“检测”代码不好;在我看来,单个标题更好。但是,您可以按任一顺序包含header_1.hheader_2.h以上,它应该可以编译。

于 2012-07-09T13:38:23.350 回答
0

我相信这是因为“模式”是使用 typedef 定义的类型,而不是结构的名称。您将需要显式转发声明它,或者您可以尝试使用如下结构的代码:

header_1.h

typedef struct
{
    struct _Mode_t **modes; 
} Library;

header_2.h

typedef struct _Mode_t
{
    int number;
    char *name;
} Mode;
于 2012-07-09T13:41:19.357 回答