Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You can't use sizeof in #if, but you can use C11 static_assert instead.

Also this doesn't just apply "in the future" -- integer types larger than intmax_t already exist, C23 just updates the standard to match reality.



You can do this:

  #if SIZEOF_PID_T > SIZEOF_UINTMAX_T
  ...
  #endif
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:

https://www.kylheku.com/cgit/txr/tree/configure?h=txr-278#n1...

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:

  #define D(N, Z) ((N) ? (N) + '0' : Z)
  #define UD(S) D((S) / 10, ' ')
  #define LD(S) D((S) % 10, '0')
  #define DEC(S) { UD(S), LD(S) }
E.g.

  DEC(42) -> /* the equivalent of */ { '4', '2' }
But actually

  DEC(42) -> { UD(42), LD(42) }
          -> { D((42) / 10, ' '), D((42) % 10, '0') }
          -> { ((42) / 10) ? ((42 / 10)) + '0' : ' ',
               ((42) % 10) ? ((42 % 10)) + '0' : '0' }
The space instead of a leading zero is so that if we pull this into shell arithmetic, it isn't confused for an octal number.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: