C 在公共头文件中使用条件句是否被认为是一种良好的做法?

C 在公共头文件中使用条件句是否被认为是一种良好的做法?,c,shared-libraries,gnu,automake,C,Shared Libraries,Gnu,Automake,我的C库有一些可选功能,使用automake,用户可以通过提供配置标志来打开和关闭这些功能 如果功能关闭,则不会编译该函数 然而,我的问题是,在这种情况下,我是否应该从公共头中删除函数原型 为未编译的函数提供函数原型似乎不是一个好主意,但在我看来,根据库配置安装不同的公共头也不是一个好主意。(类似于在public headers目录中安装config.h的错误做法。) 当涉及到可选功能时,公共标题的最佳方法是什么?如果用户试图使用禁用的功能,那么错误应该出现在编译时还是链接时?对于这种情况,必须

我的C库有一些可选功能,使用automake,用户可以通过提供配置标志来打开和关闭这些功能

如果功能关闭,则不会编译该函数

然而,我的问题是,在这种情况下,我是否应该从公共头中删除函数原型

为未编译的函数提供函数原型似乎不是一个好主意,但在我看来,根据库配置安装不同的公共头也不是一个好主意。(类似于在public headers目录中安装
config.h
的错误做法。)


当涉及到可选功能时,公共标题的最佳方法是什么?如果用户试图使用禁用的功能,那么错误应该出现在编译时还是链接时?对于这种情况,必须有一个标准的做法。(如果有多种想法,我更愿意遵守GNU编码标准,但我不知道GNU标准在这个问题上。)

我认为有两种有效的方法解决这个问题

  • 有一个头文件,它使用
    #ifdef
    删除某些配置中不支持的功能
  • 有多个头文件,其中没有
    #ifdef
    ,每个头文件都特定于一个配置

对于给定的配置,将lib中不存在的函数保留在头文件中似乎是一种非常糟糕的做法。它将采取什么应该是编译时错误,并将其移动到一个链接器之一

明确地说,不仅要将实现从编译中排除,还要将整个函数排除在外

//feature.h
#ifndef EXCLUDE_FEATURE
   void foo();
#endif

//feature.c
#include "feature.h"
#ifndef EXCLUDE_FEATURE
void foo()
{
}
#endif
这样,如果您尝试在排除特性的情况下使用
foo
,您将得到一个编译器而不是链接器错误。您希望尽快发出错误信号,链接器错误通常传递的关于开发人员意图的信息较少


微软为MFC做了这个(头文件中的条件),它工作得很好。当然,这是C++,但是原理是成立的。

< P>我在一些项目中观察到以下方法:从模板生成头文件一。 文件生成基于配置标志

在我看来,这种方法比在标题中使用永无止境的条件定义更干净……在我看来,它更干净


缺点:这可能是一个支持负担(对于脚本).

我认为如果没有定义函数,最好不要包含原型,这样错误会在编译时而不是链接时发现,但我不知道这方面有任何标准做法。我会使用#if.@VaughnCato如果原型被预处理器指令排除,你会得到一个编译器错误。@LuchianGrigore是的,准确无误ly.@LuchianGrigore是的,这正是问题的关键:如果你让预处理器排除了实现,那么也要去掉声明,这样人们就会得到编译器错误而不是链接器错误(也可能是动态链接!)“删除”是什么意思?实际删除文本吗?我会用它来有效地删除它,而不是实际删除文本。我不喜欢第二个建议,你可以手动地意外地包含文件。@ LuChanangGigor我同意这不是我的偏好。我认为这是一个步骤,上面把它们都放在一个文件中,虽然没有COD。e> #ifdefs好的,谢谢。我考虑过这一点,我唯一担心的是,它似乎与包括config.h文件非常相似——我的印象是,特定的库配置不必反映在标题中,因为可以安装多个版本的库。这确实是我的想法我们只关心这种方法。