为什么不允许多次定义C结构的成员?

时间:2012-04-25 17:14:52

标签: c struct header-files include-guards

C中的规则不止一次声明一个结构的成员似乎是我必须包含防护的主要原因。如果我们在“header.h”中有以下内容:

struct s {
    int a;
    char b;
};

和文件“a.h”#include的header.h,然后我们不能同时包含“a.h”和“header.h”,因为struct s被定义了两次。

我的问题是,这样做有什么问题?为什么不能允许多个相同的结构定义?这将消除对包含警卫的需要,并极大地清理C头文件。

C中的规则是允许多个声明,但只允许一个定义。出于某种原因,指定结构的成员称为“定义”,即使它没有定义变量或函数。

3 个答案:

答案 0 :(得分:1)

重新定义结构非常容易出错。即使在你的简单例子中,如果a.h包含一个#pragma,它在包含“header.h”之前调整结构打包或对齐,那么这两个定义可能不一定相同。这种类型的问题很难调试,因为它依赖于头部包含顺序。

通常,在允许数据类型重新定义时,可能会出现许多问题。作为交换,除了能够丢弃头部防护之外,你不会从中获得任何实际好处。标题保护解决了这个问题,并且只是一小部分开销,不会不合理地混乱代码。有些编译器支持#pragma once(或类似的)作为包含守卫,但只需要一行代码。

在我个人看来,默认情况下防止多重包含是一个更好的主意,并且只需要在设计的标题上多次包含保护宏(留下使用开销)在广大少数民族中的案例)。这不是C最初实现的方式(加上它会使预处理器变得更复杂),所以它永远不会发生变化。

答案 1 :(得分:0)

嗯,就像C一样......它的定义是因为它提供了对象的实际实现。

答案 2 :(得分:0)

你不能定义它们两次,因为正如@Kirilenko所说,定义是提供对象的实现。但是,我想知道你的问题是否也在问别的问题。

编辑:将实例化更改为定义。

您对s的定义

struct s {
    int a;
    char b;
};

会进入.c文件,或者至少你要在.h文件中对结构进行extern并将结构实例化放在.c文件中,或者在.h文件中使用typedef。

typedef struct s {
    int a;
    char b;
} my_struct_type;

即使您想要在.h文件中定义的结构,也可以通过包围这样的方式阻止其“被定义两次”

编辑:从宏中删除了下划线     #ifdef MY_STRUCT_DEFINED         struct s {             int a;             char b;         };     #ENDIF