0

在我看来,C 中反对多次声明结构成员的规则似乎是需要包含守卫的主要原因。如果我们在“header.h”中有以下内容:

struct s {
    int a;
    char b;
};

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

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

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

4

3 回答 3

1

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

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

在我个人看来,默认情况下防止多次包含会是一个更好的主意,并且仅在设计为多次包含的标头上需要保护宏(将开销留给极少数的用例)。不过,这不是 C 最初实现的方式(而且它会使预处理器更加复杂),因此它极不可能改变。

于 2012-04-25T17:32:57.040 回答
0

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

于 2012-04-25T17:22:00.087 回答
0

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

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

你对 s 的定义

struct s {
    int a;
    char b;
};

将进入 .c 文件,或者至少您可以将结构外部化到 .h 文件中并将结构实例化放在 .c 文件中,或者在 .h 文件中使用 typedef 。

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

即使您希望在 .h 文件中定义结构,也可以通过像这样的括号来防止其“被定义两次”

编辑:从宏 #ifdef MY_STRUCT_DEFINED struct s { int a; 中删除了下划线 字符 b; }; #万一

于 2012-04-25T17:42:02.963 回答