The headers stdio.h, stdlib.h, string.h declare size_t, NULL, etc.
Why declaring size_t, NULL, etc. instead of #include <stddef.h>?
The headers stdio.h, stdlib.h, string.h declare size_t, NULL, etc.
Why declaring size_t, NULL, etc. instead of #include <stddef.h>?
On
Because that's what the C standard says to do:
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 is in fact the section for <stddef.h>.
Per C17 7.19/3,
stddef.hdoes defineNULL, so the question is unfounded. Inasmuch as the premise seems to be in part that the role served bystddef.hmakes it a good place forNULLto be defined, the standard committee seems to agree.stdio.h(7.21.1/2),stdlib.h(7.22/3), andstring.h(7.24.1/1) also defineNULL. As to why this is, I am inclined to say that a combination of historical variation in which headers defined which macros plays a part, but it is also the case that each of these headers declare at least one function whose arguments and / or return value attribute specific significance to null pointers. For example,fopen()returns a null pointer when it fails. Although it is not essential to use the macroNULLto represent a null pointer constant, it is highly idiomatic, so ensuring that these headers define it makes it accessible in at least most of the standard library cases where it will be wanted, without requiring inclusion of a header just for that purpose.Similar applies for
size_t, less the historical variation angle.Addendum
Upon review, I think I initially misread the question. However, to the extent that it inquires about why the spec says that
stdio.hetc. define various identifiers that are also defined bystddef.h, when it could instead specify that those headers#include <stddef.h>, I think it still largely comes down to each header providing all the declarations it needs, so as to stand substantially on its own.Additionally, however, if the spec said (for example) that
string.hincludedstddef.hthen that would make all identifiers specified to be declared by the latter reserved (in various senses) in any translation unit that includes the former, pursuant to section 7.1.3 of the spec. By instead specifying that particular identifiers are declared or defined instring.h, only those specific identifiers are reserved by inclusion ofstring.h.