如果未定义检查布尔宏,则生成错误
我有几个配置文件,每个配置文件包含一些布尔宏的定义,设置为0或1.然后,在我的代码中,我检查这样一个宏的值,以决定激活代码的哪一部分。 现在是棘手的部分:我想确保包含我的宏定义的标题。
在下面的示例中,如果我忘记包含包含FOO定义的头文件,编译器将打印“world!”,而我希望它生成错误。
//in the configuration header file #define FOO 1 //in a cpp file #if FOO //I would like this to generate an error if I forgot to include the header file #pragma message "Hello" #else #pragma message "world!" #endif
有可能实现这样的行为吗? 怎么样?
为了澄清,我不是问如果没有定义宏,如何生成错误 ,但是如果可以转换#if FOO
行,那么同时它会检查布尔值并在FOO
生成错误没有定义。
这样做的关键是开发人员会知道他们的代码应该包含
SPECIAL_MACRO(FOO)
同时,检查FOO的布尔值,好像它是#if FOO
语句,并防止他们忘记包含定义FOO
的头。
同事们(喜欢Hartmut,Kurt)维护了一个庞大的代码库,这个代码库经过了大量的#define
配置,完全遇到了同样的问题。 一个简单的错误拼写,可能在make文件中,可能会导致难以追踪的细微错误。 他们的解决方案: 使用函数宏! 在
#if SOME_COND() // ... #endif
如果没有定义SOME_COND(),编译器会抱怨,而不是简单的SOME_COND,如果未定义,它将被0替换。 我喜欢它,因为它可以用于传输多个值而不会使用额外的#ifdef
混淆代码。
使用函数宏的公认答案是好的,但是如果你想保留普通的宏 – 并且如果定义仍然使用FOO的值并生成错误,否则你可以这样做:
#if FOO / defined(FOO) #else #endif
如果未定义FOO
,则将触发整数除以零。
使用-Wundef
gcc预处理器选项怎么样? 这只会生成一个警告,使用-Werror=undef
可以很容易地将其转换为错误。
我认为可以通过简单的棘手解决方案解决您的问题。 我改变你的代码如下,我的代码知道header.h不存在,并向我显示错误。
#if FOO == 1 #pragma message "Hello" #elif FOO == 2 #pragma message "world!" #else throw std::invalid_argument("Header didn't add to project"); #endif
只需要更改Foo的初始值。 因为编译器在找不到FOO时激活Foo == 0,所以不应该为配置使用0值。 你应该留下零标题缺席情况。你必须使用大于零的值(1,2,3,…)。
Foo == 0缺席情况。
Foo == 1配置1。
Foo == 2配置2。
。
。
。