> C90, or any version of standard C, does not have a concept of "system > headers", other than giving implementations permission to place their > own implementation-defined files in places searched by #include > <h-char-sequence>.
At this point I was talking about POSIX of course. C90 doesn't give implementations permission to place their own implementation-defined. If your program relays on that, and include some ot these implementation headers, then your program is not C90 compliant, and the behaviour is undefined (from C90 point of view, not from POSIX point of view). > POSIX does not, as far as I can tell, allow systems to require headers > to be included in any certain order. > > I have no idea what the categories "system headers" and "libc headers" We were using these informal names for C90 or C99 includes (libc headers), and POSIX headers (system headers). Of course it was a very informal way of telling them. > I couldn't find the guarantee you mentioned, that one header shall not > include another header, and I can't think of how doing so would affect > the behavior of any strictly conforming program. The guarantee is that any standard header (ISO standard) will not include another standard heard (ISO standard), but it can include another headers of the compiler. C90 standard: 4.1.2 Standard headers Each library function is declared in a header, whose contents are made available by the #include preprocessing directive. The header declares a set of related functions, plus any necessary types and additional macros needed to facilitate their use. Each header declares and defines only those identifiers listed in its associated section. ... Any function declared in a header may be implemented as a macro defined in the header, so a library function should not be declared explicitly if its header is included. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro. The use of #undef to remove any macro definition will also ensure that an actual function is referred to. Any invocation of a library function that is implemented as a macro will expand to code that evaluates each of its arguments exactly once, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments. Likewise, those function-like macros described in the following sections may be invoked in an expression anywhere a function with a compatible return type could be called Important points: - Each header declares and defines only those identifiers listed in its associated section: If the header includes another header then it will break this rule. - Any function declared in a header may be implemented as a macro defined in the header, ...For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro: If the header include another header then it can expose a macro definition of a standard function #include <stdio.h> int main(void) { int isdigit(int); int (*fn)(int) = isdigit; return (*fn)('9'); } if stdio.h includes ctype.h then this compliant program can generate errors in compile time if isdigit is a macro. If you want I can give you more references, like for example "The Standard C library" of P.J. Plauger, pag 7: The headers have several properties: - They are idempotent. You can include the same standard header more than once. The effect is as if you can included it exactly once. - They are mutually independent. No standard header requires that another standard header be first included for it to work properly. Nor does any standard header incude another standard header. Regards,