代码之家  ›  专栏  ›  技术社区  ›  user1202136

HAVE_*宏的目的是什么?

  •  4
  • user1202136  · 技术社区  · 7 年前

    我在CMake项目中重用了autotools项目中的一些C/C++源文件,我看到许多源文件中都有这样的行:

    #ifdef HAVE_UNISTD_H
    #include <unistd.h>  // for getpid()
    #endif
    

    getpid() 是可选的,其调用被等价项包围 HAVE_UNISTD_H HAVE_UNISTD_H getpid() 未定义。这比编译器告诉我的感觉要神秘得多 unistd.h

    HAVE_STDINT_H , HAVE_INTTYPES_H

    HAVE_* 有警卫吗?我觉得它们只会带来缺点:

    • 重用此类源文件需要确保存在正确的头文件 有_*
    • 在出现错误的情况下,开发人员会收到一条更隐秘的消息,即编译器不会报告根本原因(未找到头),而是报告一个辅助错误(未找到类型/函数)。
    • 源文件有点长,读起来有点乏味,即。, #include #ifdef
    2 回复  |  直到 7 年前
        1
  •  12
  •   user4815162342    7 年前

    大多数 HAVE_xxx_h 守卫是POSIX出现并标准化头文件之前时代的遗留物。在90年代初,你很容易遇到一个系统 getpid() ,但没有工作 unistd.h -函数只需在另一个头文件中声明,或者根本不声明,但由于声明在K&中是可选的,因此它仍然可以工作(只要其返回值为int大小);R和C89 C。

    time.h ,已发货 sys/time.h ,以及那些同时提供这两种功能的组件-除了最后一个类别中有一个子集,如果试图同时包含这两个功能,则会导致编译错误!支持大量这样的系统,在可能的情况下不预先列出它们,是Autoconf明确的设计目标之一,一些长期不相关的黑客仍然存在 carefully documented .

        2
  •  1
  •   user0042    7 年前

    为什么有警卫?我觉得他们只会带来缺点:。。。

    愚蠢的 1. 例子:

    #ifdef HAVE_UNISTD_H
    #include <unistd.h>  // for getpid()
    #endif
    #ifdef HAVE_WINDoWS_H
    #include <windows.h> // for GetProcessId()
    #endif
    

    1. getpid()