1

我最近意识到,虽然在给定的翻译单元中多次定义某些东西是非法的,但随意多次声明事物(函数、变量、结构)是完全合法的。我的印象是包含守卫的目的是防止重复声明。

事实上,它们的目的似乎是为了防止重复定义然而,由于函数和变量定义正确地属于 .c 文件而不是 .h 文件,并且只有 .h 文件是# include'd,这似乎意味着只有结构和联合存在问题(因为我们通常在 . h 文件,而不仅仅是声明它们)。(甚至维基百科页面上的示例包含警卫使用结构定义)。

我的问题是:为什么在头文件中定义结构如此普遍?难道我们不能在头文件中声明它们,然后将它们的定义放在 .c 文件中,然后完全不需要包含警卫,因为重复声明是可以的?

如果我不得不猜测,那是因为如果我们这样做了,那么包含此类头文件的源文件唯一能够这样做的就是创建指向结构的指针,因为它们包含的字段的定义在其他一些 .c 文件中. 那准确吗?

4

2 回答 2

4

为了有意义地使用结构类型,即为了能够访问其内容,定义该结构类型的对象,要知道该结构类型的大小,您必须定义该结构类型。该定义必须在您要使用上述结构类型的每个翻译单元中可见。这就是您要在头文件中定义结构类型的原因。

如果您只是在头文件中声明结构类型,您将无法执行任何操作。对声明的(但未定义的)结构类型唯一可以做的就是声明指向该结构类型的指针。这是一个有价值的辅助功能,但它本身完全没有用。

作为附加说明,包含保护不仅用于防止结构类型的多个定义。C 语言还禁止重复typedef声明(C++ 特别允许它们)、重复的静态函数定义、重复的静态变量定义、重复的宏定义、重复的枚举定义以及可能的其他东西。

但是你是对的,如果你的头文件只包含可以在同一个翻译单元中合法重复的声明,那么正式地你不需要在那个头文件中包含保护。

于 2013-12-06T03:15:41.253 回答
3

OP:我的问题是:为什么在头文件中定义结构如此普遍?

多个 .c 文件使用的结构需要共享相同的定义,在 .h 文件中也是如此。

单个 .c 文件的本地结构(使它们有效地“静态”或具有本地范围)应在 .c 文件中声明,而不是在配对的 .h 文件中声明。

在这种情况下需要包括防护装置以进行维护。正如 OP 所说,结构定义可以在 .c 文件中并以这种方式共享(相同),但这会带来维护的噩梦。声明/定义共享结构+once_,然后可以将它们维护在一个地方。

于 2013-12-06T03:16:11.140 回答