如果未定义检查布尔宏,则生成错误

我有几个配置文件,每个配置文件包含一些布尔宏的定义,设置为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。