系统头文件中的条件编译
Conditional compilation in system header files
头文件(如<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 版本中使用哪些内置定义。
- 如何摆脱为条件编译定义预处理器宏的需要?
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- 基于宏中传递的字符串的条件编译
- Eclipse CDT 条件编译?
- 除了使用 #define 进行条件编译之外,还有其他选择吗?
- 为什么有条件编译运算符模板会更改另一个运算符的可用性?
- C 模板:如何根据数据类型有条件编译不同的代码
- 多个条件编译符号
- 如何在不弄乱库 API 的情况下实现条件编译?
- #ifdef SWIG:什么时候考虑这种条件编译
- 预处理器和模板参数或代码段的条件编译
- 条件编译和非类型模板参数
- 模板的条件编译
- 我们有没有像c一样用java进行条件编译
- 模板模板条件编译
- 基于模板值的条件编译
- 类的条件编译
- 系统头文件中的条件编译
- 与 32 位和 64 位应用程序相同的源代码的条件编译
- 基于windows版本的c++条件编译