I dimly remember a rule that "No header of the C standard library shall include any other header of the C standard library, except where specifically allowed". But curiously, I couldn't find such a rule written down in C11. I would have expected it in 7.1.2 "Standard headers".
Searching the C Standards from Ansi-C (C90) up to the latest draft, and further scanning historic references such as Unix V7 manuals and the K&R books, I could not find a reference to this rule.
The contents, location and implementation of standard header is implementation specific, some types and macros are defined in multiple headers, so a consistent scheme to avoid redefinition warnings is necessary, and is implemented via conditional inclusion in common C library implementations.
Some systems headers are specifically specified as including other headers:
7.25 Type-generic math
<tgmath.h>The header
<tgmath.h>includes the headers<math.h>and<complex.h>and defines several type-generic macros.
7.26 Threads
<threads.h>
7.26.1 Introduction
The header<threads.h>includes the header<time.h>, defines macros, and declares types, enumeration constants, and functions that support multiple threads of execution.
Some standard POSIX headers are also documented as including other system headers.
Unless a programmer is implementing the C library, the rule would make no difference anyway: system headers documented as defining a standard type, enumeration constant, macro, function or variable should be included before this identifier is used. System headers can be included in any order, multiple inclusion should not cause any problem.
As far as I could see, it is not stated explicitly as permissible (or not). But I believe the possibility is implied by the following passage
7.1.2 Standard headers (emphasis mine)
4 If used, a header shall be included outside of any external declaration or definition, and it shall first be included before the first reference to any of the functions or objects it declares, or to any of the types or macros it defines.
When we cross reference this "shall" requirement against its meaning in the conformance section
4. Conformance
2 If a "shall" or "shall not" requirement that appears outside of a constraint or runtime- constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words "undefined behavior" or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe "behavior that is undefined".
So if one were to call the abs function without including stdlib.h, the behavior would be undefined. Undefined behavior by its very nature includes the possibility of things "working". And so, if another standard header includes stdlib.h and the program "works", this is inline with the contract stated above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With