我有几个配置文件,每个配置文件包含一些布尔宏的定义,要设置为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
是否有可能实现这样的行为?怎么样?
为了澄清,我不是在问how to generate an error if a macro is not defined,而是如果可以转换#if FOO
行,同时它会检查布尔值并在{{{{}}时生成错误1}}未定义。
这样做的关键是开发人员会知道他们的代码应该包含
FOO
同时检查FOO的布尔值,就好像它是SPECIAL_MACRO(FOO)
语句一样,并防止它们忘记包含定义#if FOO
的标题。
答案 0 :(得分:26)
同事(嗨Hartmut,Kurt)维护了一个庞大的代码库,这个代码库已经广泛配置了#define
s,完全遇到了同样的问题。一个简单的错误拼写,可能在make文件中,可能会导致难以追踪的细微错误。他们的解决方案:使用功能宏!在
#if SOME_COND()
// ...
#endif
如果没有定义SOME_COND(),编译器会抱怨,而不是简单的SOME_COND,如果未定义,它将被0替换。我喜欢它,因为它可用于传输多个值,而不会使用额外的#ifdef
s使代码混乱。
答案 1 :(得分:3)
使用函数宏的接受答案是好的,但是如果你想保留普通的宏 - 并且如果定义仍然使用FOO的值并产生错误,否则你可以这样做:
#if FOO / defined(FOO)
#else
#endif
如果未定义FOO
,则会触发整数除以零。
答案 2 :(得分:2)
使用-Wundef
gcc预处理器选项怎么样?这只会生成警告,使用-Werror=undef
很容易将其转为错误。
答案 3 :(得分:2)
宏generator\plugins
将:
CHECK(x)
,则失败,x
被定义为00
,则评估为x
0
被定义为01
,则评估为x
1
答案 4 :(得分:-1)
我认为可以通过简单的棘手解决方案解决您的问题。我更改了您的代码,我的代码知道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。