[英]What is the purpose of HAVE_* macros?
I am reusing some C/C++ source files part of an autotools project within a CMake project and I see many source files littered with lines like: 我正在重用CMake项目中的一些autotools项目的一些C / C ++源文件,我看到许多源文件散落着如下行:
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for getpid()
#endif
I would understand the purpose of this construct if getpid()
was optional and its call was surrounded by equivalent HAVE_UNISTD_H
directives. 如果
getpid()
是可选的并且它的调用被等效的HAVE_UNISTD_H
指令包围,我会理解这个构造的目的。 However, without HAVE_UNISTD_H
the source file does not compile, complaining that getpid()
is not defined. 但是,如果没有
HAVE_UNISTD_H
,源文件将无法编译,抱怨未定义getpid()
。 This feels a lot more cryptic than the compiler letting me know that unistd.h
was not found. 这比编译器让我知道没有找到
unistd.h
感觉更加神秘。
Of course, this is only an example. 当然,这只是一个例子。 Other popular macros include
HAVE_STDINT_H
, HAVE_INTTYPES_H
, etc. whose presence is mandatory to compile the source file. 其他流行的宏包括
HAVE_STDINT_H
, HAVE_INTTYPES_H
等,其存在是编译源文件所必需的。
Why are HAVE_*
guards included at all? 为什么包括
HAVE_*
警卫? I feel they only bring disadvantages: 我觉得他们只会带来不利因素:
HAVE_*
macros are defined. HAVE_*
宏。 #include
s mixed with #ifdef
s. #include
与#ifdef
混合。 Most of the HAVE_xxx_h
guards are remnants from an era before POSIX came along and standardized the header files. 大多数
HAVE_xxx_h
警卫都是POSIX出现之前的一个时代的残余,并标准化了头文件。 In early 90s you could easily come across a system that did have getpid()
, but without a working unistd.h
- the function would simply be declared in another header file, or it wouldn't be declared at all, but it would still work (as long as its return value was int-sized) due to declarations being optional in K&R and C89 C. 在90年代早期,您可以很容易地遇到一个确实有
getpid()
,但没有工作的unistd.h
- 该函数只是在另一个头文件中声明,或者它根本不会被声明,但它仍然会由于声明在K&R和C89 C中是可选的,因此工作(只要其返回值是int大小)。
There were even stranger issues between the multitude of systems in use at the time. 当时使用的众多系统之间甚至存在奇怪的问题。 For example there were systems that shipped
time.h
, those that shipped sys/time.h
, and those that shipped both - except that among the last category there was a subset where attempting to actually include both would result in a compilation error! 例如,有些系统运行
time.h
,那些运送sys/time.h
,以及运送它们的系统 - 除了在最后一个类别中有一个子集,其中试图实际包含两者都会导致编译错误! Supporting a vast array of such systems, where possible without listing them all in advance, was one of the explicit design goals of Autoconf, and some of the long-irrelevant hacks are still carefully documented . 支持大量此类系统,尽可能不提前列出所有这些系统,是Autoconf的明确设计目标之一,而且一些长期无关的黑客仍然需要仔细记录 。
In addition to the above concerns, decoupling the header names from support for functions can come in useful when porting the code to non-POSIX systems such as windows. 除了上述问题之外,在将代码移植到非POSIX系统(如Windows)时,将头名称与函数支持分离可能会很有用。 On such systems the posix headers might be missing or broken, and the actual function definition comes from a portability library such as gnulib.
在这样的系统上,posix标头可能丢失或损坏,实际的函数定义来自可移植性库,例如gnulib。
Why are HAVE_* guards included at all?
为什么包括HAVE_ *警卫? I feel they only bring disadvantages: ...
我觉得他们只会带来不利因素:......
A source could approach an alternative implementation. 源可以接近替代实现。 In that case you certainly don't want to get errors for missing includes.
在这种情况下,您当然不希望因缺少包含而出错。
Silly 1 example: 傻1例:
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for getpid()
#endif
#ifdef HAVE_WINDoWS_H
#include <windows.h> // for GetProcessId()
#endif
1 I know that windows supports getpid()
. 1 我知道windows支持
getpid()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.