My program was first written when intmax_t already existed; AFAICT, intmax_t was introduced in C99. I also need to parse and/or print uid_d, gid_t, and pid_t, so I guess that in the future I’ll have to implement my own integer parser and printer, like user “orlp” suggested elsethread.
Where you detect these sizes from the toolchain and deposit them as #define constants in some "config.h" header.
There are ways to detect sizes by compiling a source file to an object file, and then analyzing the object file (no execution), so things work under cross-compiling.
I've used a number of tricks over the years, and settled on this one:
The basic idea is that we can take a value like sizeof(long), which is a constant, and using nothing but constant arithmetic, we can convert it to the characters " 8". These characters can be placed into a character array where they are delimited by some prefix that we can look for in the compiled object file with some common utilities.
This is quite durable in the sense that it can be reasonably expected to work through a wide variety of object formats.
In that test program, I have a structure with some character arrays. The larger character arrays hold the informative prefixes. The two-byte arrays hold decimal digits for sizes. Two digits go up to 99 bytes so we are safe for a number of years.
The DEC macro calculates the ASCII decimal value of its argument, expanding to a two-byte initializer for a character array: