在公共头文件中使用条件是一种良好的做法吗?

时间:2012-03-09 18:34:02

标签: c shared-libraries gnu automake

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

如果关闭某项功能,则不会编译该功能。

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

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

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

3 个答案:

答案 0 :(得分:3)

定义不仅要从编译中排除实现,还要排除整个函数。

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

//feature.c
#include "feature.h"
#ifndef EXCLUDE_FEATURE
void foo()
{
}
#endif

这样,如果您尝试在排除该功能的情况下使用foo,您将获得编译器,而不是链接器错误。您希望尽快发出错误信号,链接器错误通常会减少开发人员的意图。

Microsoft为MFC做了这个(头文件中的条件)并且它运行得很好。 (当然那是C ++,但原则就是这样。

答案 1 :(得分:1)

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

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

在给定配置的头文件中保留lib中不存在的函数似乎是一种非常糟糕的做法。它将需要编译时错误并将其移动到链接器1。

答案 2 :(得分:1)

我在一些项目中观察到以下方法:从模板1生成头文件。

文件生成基于配置标志。

这种方法在我看来比在标题中使用永不停止的条件定义更清晰...对我来说它看起来更干净。

缺点:它可能是一种支持负担(对于脚本而言)。