【问题标题】:Include header file only if it is available in C?仅当它在 C 中可用时才包含头文件?
【发布时间】:2020-06-15 14:58:42
【问题描述】:

我想将 pthread 的逻辑添加到我正在为 C 编写的小型分析库中。但是,如果 pthread 可用,我只想执行与 pthread 相关的逻辑。

是否有使用预处理器指令的编程方式来执行此操作?

我想它看起来像:

#ifdef pthread_h
#include <pthread.h>
#endif

. . .


#ifdef pthread_h
// pthread specific logic here
#endif

但我不确定并且不知道如何处理的部分是

#ifdef pthread_h

如果我还没有包含pthread.h,则pthread_h 不可用。对?

有没有办法只在头文件可用时才包含它?也许我可以通过这种方式实现我正在寻找的结果。


我想要的结果是在分析数据中包含有关当前线程 ID 的信息,但前提是库具有可用于调用 pthread_self() 的 pthread。

【问题讨论】:

  • Linked != included。这是不同的东西。没有什么是链接编译时间。库是 linked 在编译后发生的链接期间,通常由名为 linker 的单独程序完成。
  • 除了关于链接过程的错误措辞。为什么提供的示例不适合您?为什么以及因为什么你特别不确定?
  • 提供的示例对我不起作用,因为我不知道如果在包含 pthread.h 之前无法定义 pthread_h 会在哪里定义它。我是否可以尝试包含文件但如果找不到则失败?也许我可以根据可用的标头而不是可用的库来做到这一点。
  • @P__J__ 我已经修改了问题,希望该术语现在更有意义。我对 C 不是很熟悉,所以我在这里。
  • 了解GNU autoconf

标签: c macros include c-preprocessor header-files


【解决方案1】:

有没有办法只在头文件可用的情况下才包含它?也许我可以通过这种方式实现我正在寻找的结果。

是的。如果您的编译器支持,您可以使用即__has_include 宏:

#if defined __has_include
#  if __has_include (<pthread.h>)
#    include <pthread.h>
#  endif
#endif

...

#if defined __has_include
#  if __has_include (<pthread.h>)
#    // pthread specific logic here
#  endif
#endif

旁注:

  • "...如果 pthread 在编译时实际上已经被链接。"

链接过程不是在编译时完成的。它出现在编译之后。 C 预处理器甚至在编译之前就完成了它的工作。

【讨论】:

    【解决方案2】:

    我找到了我最喜欢的解决方案。它似乎是最便携和最直接的。

    如果用户希望使用 pthread,只需在编译时指示用户使用 -D PROF_WITH_PTHREA=1 进行编译,然后在 C 源代码中检查该预处理器指令,然后再使用 pthread 进行任何操作。

    $ gcc -I./ -o test text.c -lpthread -D PROF_WITH_PTHREAD=1
    
    #ifdef PROF_WITH_PTHREAD
    #include <pthread.h>
    #endif
    
    . . .
    
    #ifdef PROF_WITH_PTHREAD
    // pthread specific logic here
    #endif
    

    虽然这不会检查库是否可用或检查标头是否可用,但它实现了我想要的结果,并且以非常直接和简单的方式完成。

    【讨论】:

    • 你应该引用引用的来源,内森。通过这种方式,您可以帮助其他人找到您找到的解决方案的来源。
    • 我看到你使用 GCC。只是出于兴趣:我的答案中显示的 __has_include 宏不适合您吗?它在 GCC 中得到支持,并且完全符合您的要求 - 直接使用预处理器宏检查库是否可用,而无需任何额外的编译器选项,如 -D PROF_WITH_PTHREAD=1(当然 -pthread 除外)。这种方法的确切优势是什么使您更喜欢它?我在答案中看不到这一点。 - “它似乎是最便携和最直接的。”给人一种意见的印象。
    • @RobertSsupportsMonicaCellio 这实际上不是报价。这只是格式化的一个糟糕的选择。我会解决的。而且我认为允许使用预处理指令的编译时定义比要求用户使用 GCC 更具可移植性。
    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多