【问题标题】:Check whether function is declared with C preprocessor?检查函数是否用 C 预处理器声明?
【发布时间】:2009-11-17 14:24:37
【问题描述】:

是否可以告诉 C 预处理器检查是否声明了函数(不是宏)?我尝试了以下方法,但它似乎不起作用:

#include <stdio.h>

int main(void)
{
#if defined(printf)
    printf("You support printf!\n");
#else
    puts("Either you don't support printf, or this test doesn't work.");
#endif
    return 0;
}

【问题讨论】:

  • 我对此原因非常感兴趣。您正在使用的库应该是一致的,以选择您的示例:没有 printf 就没有 stdio.h 并且如果 printf 可能在遥远的将来被删除,您现在将不知道替换的情况如何被调用。
  • 我认为它不是专门针对 printf 的,只是任何函数名称。但是,如果你想知道那里的功能,只需调用它 - 编译器错误会告诉你:-)
  • 我的主要动机是检查诸如 bcopy() 或 arc4random() 之类的函数(在编写跨平台程序时),这些函数并不总是被定义。
  • 有些机器有“空白”功能,有些没有。我不知道它是在哪里定义的。这本来很好,但是唉。编辑:原来是 readline/chardefs.h 中的一个宏。

标签: c macros c-preprocessor


【解决方案1】:

没有。预处理器在 C 编译器和 C 编译器处理函数声明之前运行。预处理器仅用于文本处理。

但是,大多数头文件都包含像 _STDIO_H_ 这样的保护宏,您可以在预处理器阶段对其进行测试。但是,该解决方案不可移植,因为包含保护宏名称未标准化。

【讨论】:

    【解决方案2】:

    如果您查看 autoconf 之类的工具,您会发现它们会通过许多测试来确定计算机有什么或没有什么,然后才能正确编译,然后它们会设置正确的 #DEFINES。

    如果您使用某种风格的 unix,您可能想要查看该模型和该工具,因为您想要做的事情是不可能的,正如其他人无疑指出的那样。

    【讨论】:

      【解决方案3】:

      严格来说不,预处理器不能自己完成。但是,您可以通过自动创建适当的#defines 给它一点帮助。

      通常如上所述,如果在 unix 类型系统上,您会使用 autotools。但是,您也可以使用 makefile 创建相同的效果。我最近有理由检测到头文件中定义的“posix_fallocate”函数,因为我使用的是 uClibc,它似乎在早期版本中省略了它。这在 gnu make 中有效,但您可能会在其他版本中获得类似的东西:

      NOFALLOC := $(shell echo "\#include <fcntl.h>\nint main() { posix_fallocate(0,0,0);}" | $(CC) -o /dev/null -Werror -xc - >/dev/null 2>/dev/null && echo 0 || echo 1)
      ifeq "$(NOFALLOC)" "1"
          DFLAGS += -DNO_POSIX_FALLOCATE
      endif
      

      【讨论】:

        【解决方案4】:

        预处理器是一个简单的程序,对底层语言几乎一无所知。它无法判断一个函数是否已被声明。即使可以,该函数也可能在另一个库中定义,并且符号在链接期间被解析,因此预处理器在这方面无能为力。

        【讨论】:

          【解决方案5】:

          由于预处理器不知道 C/C++ 语言(它实际上只进行文本替换),我猜这是不可能的。你为什么要这样做?也许还有其他方法。

          【讨论】:

          • 为了完整起见,我现在想这样做,因为 Ubuntu 20.04 apt 存储库上的 libcmocka-dev 似乎实际上并没有暴露 assert_float_equal 的符号。
          猜你喜欢
          • 2011-04-08
          • 1970-01-01
          • 1970-01-01
          • 2011-07-02
          • 2015-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多