系统头文件中的条件编译

时间:2014-11-21 02:50:57

标签: c++ linux architecture conditional-compilation

系统头文件(例如<sys/types.h>)中的条件编译如何控制编译过程的问题困扰了我很长一段时间 例如,这是<sys/types.h>中的一个常见typedef代码片段:

#  if __WORDSIZE == 64
typedef long int int64_t;
#  elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef long long int int64_t;
#  endif
# endif

也就是说,如果是__WORDSIZE == 64,那么我们将类型int64_t定义为long int的一个别名,但我想知道在哪里可以找到__WORDSIZE的定义。

  • 是否已在某个文件中静态定义__WORDSIZE的宏?如果 那么,这个文件是如何生成的?
  • 或者,我们将预处理器宏传递给编译器?
  • 或者,编译器知道它运行的是什么类型的机器?但是怎么知道呢?

毕竟,如何编写一个可以达到以下目的的头文件:

#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 个答案:

答案 0 :(得分:1)

这取决于编译器和系统。它(__WORDSIZE)可以由编译器定义为内置宏(可以根据编译器选项而改变),也可以在系统头中。阅读系统标题充其量是一项艰苦的工作;一般来说,你不应该试图猜测其中的内容。

请注意,__WORDSIZE位于为实现保留的命名空间中。只要它正常工作,实现可以随意使用它。如果将代码绑定到__WORDSIZE,则在更改编译器版本,编译器品牌,操作系统版本,操作系统品牌时可能会遇到问题。

关于编译器如何检测它所在的系统:这是编译器的问题。它是为特定系统(通常是主机系统,除非是交叉编译器)生成代码而构建的。编译器设置为知道如何正确编译代码;如何创建32位目标代码或程序,以及如何创建64位目标代码或程序。如果它不知道如何正确地创建代码,那么它作为编译器的用处不大,是吗?

您可以通过以下方式实现目标:

// #include <stdint.h> // C header
#include <cstdint>     // C++ analogue of <stdint.h>

typedef uint64_t KEY_TYPE;

代码中没有条件编译 - 这是编写代码的最佳方式。

警告:从技术上讲,uint64_t是一种可选类型。但是,无论它是否可用,您都会遇到问题。)

答案 1 :(得分:1)

要发现gcc内置定义(在编译任何文件之前),请尝试使用:

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

(temp.cpp只需要是一个空文件)

将-std = c ++ 11更改为您需要的标准。

其中一些内置定义将用于控制系统头文件的编译。

某些内置定义仅供内部(至gcc)使用。您需要查阅gcc文档以了解您可以在您的gcc版本中使用哪些内置定义。