Conditional compilation in system header files

1k views Asked by At

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
2

There are 2 answers

4
Jonathan Leffler On BEST ANSWER

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

0
Richard Critten On

To discover the gcc built-in defines (before any files are compiled) try using:

gcc -std=c++11 -E -P -v -dD temp.cpp

(temp.cpp just needs to be an empty file)

Change -std=c++11 to the standard you require.

Some of these built-in defines will be used to control the compilation of the system header files.

Some of the built-in defines are for internal (to gcc) use only. You will need to consult gcc documentation to discover which of the built-in defines you can use in your version of the gcc.