use*_*733 4 c c-preprocessor preprocessor-directive
背景
我有一个带有配置头文件的C项目,例如:
// config.h
#define FEATURE_1_AVAILABLE 1
#define FEATURE_2_AVAILABLE 0
#define FEATURE_3_AVAILABLE 1
Run Code Online (Sandbox Code Playgroud)
模块使用这些标志在构建中包括/排除功能:
#include "config.h"
void foo(void) {
...
#if FEATURE_1_AVAILABLE
useFeature1();
#endif
...
Run Code Online (Sandbox Code Playgroud)
有不同版本的config.h不同版本。
问题
#include "config.h" 被意外删除,因此即使在config中启用了该功能,该功能也未处于活动状态。
不幸的是,它会#if FEATURE_1_AVAILABLE默默地评估0未定义的时间。因此,如果未定义,我需要一个错误。
选项1
我可以在每个条件上添加额外的“如果定义”测试。
#ifndef FEATURE_1_AVAILABLE
#error No feature 1
#elif FEATURE_1_AVAILABLE
useFeature1();
#endif
Run Code Online (Sandbox Code Playgroud)
缺点是一个功能标记可能会在模块中的许多不同位置进行测试,并且添加多条预处理程序行不会使代码更漂亮。
选项2
在模块的开头添加单个测试:
#ifndef FEATURE_1_AVAILABLE
#error No feature 1
#endif
Run Code Online (Sandbox Code Playgroud)
但这可能会因为相同的原因而丢失/遗忘#include "config.h"。
选项3
将标志定义为宏:
#define FEATURE_1_AVAILABLE() 1
Run Code Online (Sandbox Code Playgroud)
并用作:
#if FEATURE_1_AVAILABLE()
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果您忘记括号,这也将无声地失败:
#if FEATURE_1_AVAILABLE
Run Code Online (Sandbox Code Playgroud)
选项X
有更好的选择吗?如果未定义符号或书写不正确,则会在编译时给出错误消息。并希望不会使代码看起来无法维护的预处理器混乱。
其他事情
另一个解决方案是让编译器在未定义要评估的宏时警告您。
随着gcc例如存在-Wundef选项(不包括在-Wall):
#if FEATURE_1_AVAILABLE
useFeature1();
#endif
Run Code Online (Sandbox Code Playgroud)
这给出警告(添加-Werror使其成为错误):
tst.c:6:9: warning: "FEATURE_1_AVAILABLE" is not defined [-Wundef]
#if FEATURE_1_AVAILABLE
Run Code Online (Sandbox Code Playgroud)
其他编译器(例如clang和)也可以使用此选项icc。