use*_*136 4 c c++ macros autotools
我正在重用CMake项目中的一些autotools项目的一些C/C++源文件,我看到许多源文件散落着如下行:
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for getpid()
#endif
Run Code Online (Sandbox Code Playgroud)
我会理解这个构造的目的,如果getpid()是可选的,并且它的调用被等效的HAVE_UNISTD_H指令包围.但是,没有HAVE_UNISTD_H源文件不编译,抱怨getpid()没有定义.这比让我知道unistd.h没有找到的编译器感觉更加神秘.
当然,这只是一个例子.其他流行的宏包括HAVE_STDINT_H,HAVE_INTTYPES_H等等,其存在是编译源文件所必需的.
为什么要包括HAVE_*警卫?我觉得他们只会带来不利因素:
HAVE_*定义正确的宏.#includes与#ifdefs 混合.大多数HAVE_xxx_h守卫都是POSIX出现之前的一个时代的残余,并标准化了头文件.在90年代早期,你可以很容易地遇到一个确实存在的系统getpid(),但没有工作unistd.h- 该函数只是在另一个头文件中声明,或者它根本不会被声明,但它仍然可以工作(只要它由于声明在K&R和C89 C中是可选的,因此返回值为int-size).
当时使用的众多系统之间甚至存在奇怪的问题.例如有迹象表明发售的系统time.h,那些运sys/time.h,和那些既运-最后一类中,除了在那里试图实际上包括将导致编译错误有一个子集!支持大量此类系统,尽可能不提前列出所有这些系统,是Autoconf的明确设计目标之一,而且一些长期无关的黑客仍然需要仔细记录.
除了上述问题之外,在将代码移植到非POSIX系统(如Windows)时,将头名称与函数支持分离可能会很有用.在这样的系统上,posix标头可能丢失或损坏,实际的函数定义来自可移植性库,例如gnulib.