Search code examples
c++linuxarchitectureconditional-compilation

Conditional compilation in system header files


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

Solution

  • 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:

    // #include <stdint.h> // C header
    #include <cstdint>     // C++ analogue of <stdint.h>
    
    typedef uint64_t KEY_TYPE;
    

    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.)