系统头文件中的条件编译

Conditional compilation in system header files

本文关键字:条件 编译 文件 系统      更新时间:2023-10-16
系统

头文件(如<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

这取决于编译器和系统。 它(__WORDSIZE)可以由编译器定义为内置宏(可能会根据编译器选项而更改),也可以位于系统头文件中。 读取系统标题充其量是艰苦的工作;一般来说,你不应该试图猜测它们里面有什么。

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

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

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

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

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

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

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

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

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

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

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

一些内置定义仅供内部(到 gcc)使用。 您需要查阅 gcc 文档,以发现您可以在您的 gcc 版本中使用哪些内置定义。