For the needs of a project I’m working on, I had to write an aligned allocator on top of
malloc()/realloc()/free() and a simple logger featuring different log levels and basic colouring. Nothing too fancy here.
It was obvious that the code had nothing specific to that project and was in fact a good fit for a more general-purpose library.
While developing Zero, I was influenced by the Physical Design of The Machinery and chose not to have any
#include dependency within the library headers. That’s right. Not even standard headers.  Why’s that? Because standard headers contain thousands of lines of code when counting their own dependencies and I do not want to slow down compilation times by burdening projects that include my headers into their own headers. At least, not without a good reason. Are fixed integer types or
size_t a good enough reason? Not even.
Most projects target common platforms (Windows, Linux, macOS) and hence use either the ILP32, LP64, or LLP64 data models. All of these data models guarantee the
char type to be 8 bits,
short to be 16 bits,
int to be 32 bits, and
long long to be 64 bits. For people using more exotic platforms, Zero can fallback to using
<stdint.h> if the macro
ZR_USE_STD_FIXED_TYPES is defined. Even better, each type can be overridden individually through macros such as
The same goes for
size_t—on almost all platforms the size of
size_t equals the targetted architecture, that is either 32 or 64 bits. Here again, there is a fallback macro with
ZR_USE_STD_BASIC_TYPES that includes
<stddef.h>, and a more granular one
ZR_SIZE_TYPE to directly set the size type to be used.
Note that these custom types are only used in the public interface defined within the headers. The implementation side of things is free to include whatever file is needed, which is fine since these dependencies are to remain within a single translation unit rather than spreading all over the place through the
As always, it’s all on GitHub, so go get it!