You are right that exposing unwanted types and declarations from additional headers would be non-conforming.
One trivial (but, in terms of time the preprocessor spends opening files, expensive) solution is to have a separate header for each type, and whenever you need, for example, time_t
, do:
#include <types/time_t.h>
Of course types/time_t.h
would have the appropriate multiple-inclusion guards.
There are many other ways of achieving the same. The approach glibc and gcc use is to have special "needed" macros you can define before including a header that asks it to do nothing but provide one or more types. This solution is also very expensive, probably moreso than the above, because it breaks compilers' heuristics for multiple-inclusion guards. The compiler can't elide repeated inclusions; it has to parse the file each time it's included.
The way we do it in musl is to have a single file, bits/alltypes.h
, which includes the definitions of all types which are needed by multiple headers and macros to control which are exposed. It's generated by a simple sed script that hides all the macro logic:
- http://git.musl-libc.org/cgit/musl/tree/arch/i386/bits/alltypes.h.in?id=9448b0513e2eec020fbca9c10412b83df5027a16
- http://git.musl-libc.org/cgit/musl/tree/include/alltypes.h.in?id=9448b0513e2eec020fbca9c10412b83df5027a16
- http://git.musl-libc.org/cgit/musl/tree/tools/mkalltypes.sed?id=9448b0513e2eec020fbca9c10412b83df5027a16