Compile-time sizeof conditional

This describes how to fake compile-time assertions in C. The short version is to use switch statements:

#define COMPILE_TIME_ASSERT(pred)            \  
    switch(0){case 0:case pred:;}

If pred evaluates to 0, like a false boolean expression does in C, the compiler will throw an error.


The correct solution to your problem is to use the C99 standard headers:

#include <stdint.h>
#include <inttypes.h>

You only need one of the two because #include <inttypes.h> includes the material from #include <stdint.h>; however, a lot of the material in <inttypes.h> is only relevant to formatted I/O with scanf() and printf().

Given the putative condition:

#if (sizeof(void*) <= sizeof(unsigned int)) // what goes here?
#  define POINTER_FITS_INTO_UINT
#endif

What you seem to be after is known as:

uintptr_t

That is the unsigned integer type that is big enough to hold any pointer (that is, any data pointer in the C standard; POSIX imposes an additional rule that it must also be big enough to hold function pointers too). The type uintptr_t is defined in <stdint.h>.

If you are subsequently going to be printing such values, or raw pointers, you can use the information from <inttypes.h>:

printf("Pointer = 0x%" PRIXPTR "\n", uintptr_value);
printf("Pointer = 0x%" PRIXPTR "\n", (uintptr_t)any_pointer);

Assuming C99, you could use

#include <limits.h>
#include <stdint.h>

#if UINTPTR_MAX <= UINT_MAX
...

which implies sizeof (void *) <= sizeof (intptr_t) <= sizeof (int) on any sane implementation of the C language.


You just can't do it. sizeof is a compile time operator. #if and #define and preprocessor related. As the preprocessor runs BEFORE the compiler this just won't work. You may, however, be able to find an arcane compiler switch that will allow you to multi pass it (ie preprocess, pretend compile, preprocess, compile) but, in all fairness, I'd give up trying to do what you want. Its not meant to work and, simply, it doesn't.

Your best best is to set such defines as -D commands passed to the compiler. You can statically assert that the ones chosen are correct. This way you just have to set up a few defines externally for a given compile mode (eg PowerPC Release) and so on.