我的C库有一些可选功能,使用automake,用户可以通过提供配置标志来打开和关闭它们。
如果关闭某项功能,则不会编译该功能。
但是,我的问题是,在这种情况下我是否应该从公共标题中删除函数原型?
为未编译的函数提供函数原型似乎不是一个好主意,但 似乎不是一个好主意,根据库配置安装不同的公共头文件。 (类似于在公共头文件目录中安装config.h
的不良做法。)
在可选功能方面,公共标题的最佳方法是什么?如果用户尝试使用禁用的功能,错误应该在编译时还是链接时?这种情况必须有标准做法。 (如果有多个想法,我更愿意遵守GNU编码标准,但我不知道这个问题的GNU标准。)
答案 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生成头文件。
文件生成基于配置标志。
这种方法在我看来比在标题中使用永不停止的条件定义更清晰...对我来说它看起来更干净。
缺点:它可能是一种支持负担(对于脚本而言)。