为什么 stdio.h、stdlib.h、string.h 声明 size_t、NULL 等而不是 #include <stddef.h>?
Why stdio.h, stdlib.h, string.h declare size_t, NULL, etc. instead of #include <stddef.h>?
headers stdio.h
, stdlib.h
, string.h
声明 size_t
, NULL
, 等等
为什么要声明 size_t
、NULL
等而不是 #include <stddef.h>
?
因为这是 C 标准所说的:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
7.19 Input/output <stdio.h>
7.19.1 Introduction
1 The header <stdio.h>
declares three types, several macros, and many functions for performing input and output.
2 The types declared are size_t
(described in 7.17);
[...]
3 The macros are NULL
(described in 7.17);
7.17 实际上是 <stddef.h>
.
的部分
Why declaring size_t, NULL, etc. instead of #include <stddef.h>
?
根据 C17 7.19/3,stddef.h
确实 定义了 NULL
,所以这个问题是没有根据的。由于前提似乎部分是 stddef.h
所扮演的角色使其成为定义 NULL
的好地方,标准委员会似乎同意。
stdio.h
(7.21.1/2)、stdlib.h
(7.22/3) 和 string.h
(7.24.1/1) 也定义了 NULL
。至于为什么会这样,我倾向于说历史变化的组合,其中 headers 定义了哪些宏起作用,但也有这样的情况,这些 headers 中的每一个都声明在至少一个函数,其参数和/或 return 值将特定意义赋予空指针。例如,fopen()
return在失败时是一个空指针。尽管使用宏 NULL
来表示空指针常量不是必需的,但它是高度惯用的,因此确保这些 header 定义它至少可以在大多数标准库情况下访问它在需要的地方,不需要为了那个目的而包含 header。
类似适用于 size_t
,减去历史变化角度。
附录
经过复习,我想我最初看错了问题。然而,在某种程度上,它询问了为什么规范说 stdio.h
etc。定义也由 stddef.h
定义的各种标识符,当它可以指定那些 headers #include <stddef.h>
时,我认为它仍然主要归结为每个 header 提供所有它需要的声明,以便基本上独立存在。
然而,另外,如果规范说(例如)string.h
包含 stddef.h
那么这将使所有指定的标识符在任何情况下都被后者保留(在各种意义上)声明根据规范第 7.1.3 节,包括前者的翻译单元。通过指定在 string.h
中声明或定义的特定标识符,仅通过包含 string.h
.
保留那些特定标识符
headers stdio.h
, stdlib.h
, string.h
声明 size_t
, NULL
, 等等
为什么要声明 size_t
、NULL
等而不是 #include <stddef.h>
?
因为这是 C 标准所说的:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
7.19 Input/output
<stdio.h>
7.19.1 Introduction
1 The header
<stdio.h>
declares three types, several macros, and many functions for performing input and output.2 The types declared are
size_t
(described in 7.17);[...]
3 The macros are
NULL
(described in 7.17);
7.17 实际上是 <stddef.h>
.
Why declaring size_t, NULL, etc. instead of
#include <stddef.h>
?
根据 C17 7.19/3,stddef.h
确实 定义了 NULL
,所以这个问题是没有根据的。由于前提似乎部分是 stddef.h
所扮演的角色使其成为定义 NULL
的好地方,标准委员会似乎同意。
stdio.h
(7.21.1/2)、stdlib.h
(7.22/3) 和 string.h
(7.24.1/1) 也定义了 NULL
。至于为什么会这样,我倾向于说历史变化的组合,其中 headers 定义了哪些宏起作用,但也有这样的情况,这些 headers 中的每一个都声明在至少一个函数,其参数和/或 return 值将特定意义赋予空指针。例如,fopen()
return在失败时是一个空指针。尽管使用宏 NULL
来表示空指针常量不是必需的,但它是高度惯用的,因此确保这些 header 定义它至少可以在大多数标准库情况下访问它在需要的地方,不需要为了那个目的而包含 header。
类似适用于 size_t
,减去历史变化角度。
附录
经过复习,我想我最初看错了问题。然而,在某种程度上,它询问了为什么规范说 stdio.h
etc。定义也由 stddef.h
定义的各种标识符,当它可以指定那些 headers #include <stddef.h>
时,我认为它仍然主要归结为每个 header 提供所有它需要的声明,以便基本上独立存在。
然而,另外,如果规范说(例如)string.h
包含 stddef.h
那么这将使所有指定的标识符在任何情况下都被后者保留(在各种意义上)声明根据规范第 7.1.3 节,包括前者的翻译单元。通过指定在 string.h
中声明或定义的特定标识符,仅通过包含 string.h
.