The question that how the conditional compilation in the system header files (such as <sys/types.h>
) control the compiling process confused me for a long time
For example, here's one common typedef code fragment in <sys/types.h>
:
# if __WORDSIZE == 64
typedef long int int64_t;
# elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef long long int int64_t;
# endif
# endif
That said, if __WORDSIZE == 64
, then we define the type int64_t
as one alias of long int
, but I wonder that where can I find the definition of __WORDSIZE
.
- Has the macro of
__WORDSIZE
been defined statically in some file? If so, how does this file get generated? - Or, we pass the preprocessor macros to the compiler?
- Or, the compiler know on what kind of machine it is running exactly? But how does it know?
After all, how can I write one header file that can achieve the following intention:
#if the machine is 64-bit
typedef unsigned long int KEY_TYPE
#elif the machine is 32-bit
typedef unsigned long long int KEY_TYPE
#endif
It depends on the compiler and the system. It (
__WORDSIZE
) may be defined by the compiler as a built-in macro (that may change depending on compiler options), or it may be in a system header. Reading system headers is hard work at best; in general, you should not be trying to second-guess what's in them.Note that
__WORDSIZE
is in the namespace reserved for the implementation. The implementation may do as it likes with it as long is it works correctly. If you tie your code to__WORDSIZE
, you may run into problems when you change compiler versions, compiler brands, operating system versions, operating system brands.As to how the compiler detects what system it is on: that is the compiler's problem. It is built to generate code for a specific system (usually the host system, unless it is a cross-compiler). The compiler is set up to know how to compile code correctly; how to create 32-bit object code or programs, and how to create 64-bit object code or programs. It wouldn't be much use as a compiler if it did not know how to create the code correctly, would it?
You can achieve your goal with:
No conditional compilation in your code — that's the best way to write the code.
(Caveat: Technically,
uint64_t
is an optional type. However, it looks like you'll have problems regardless if it is not available.)