系统头文件(例如<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
答案 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版本中使用哪些内置定义。