如果未定义选中的布尔宏,则会生成错误
Generating an error if checked boolean macro is not defined
我有几个配置文件,每个配置文件都包含一些布尔宏的定义,设置为 0 或 1。然后,在我的代码中,我检查这样一个宏的值来决定代码的哪一部分启用。现在是棘手的部分:我想确保包含我的宏定义的 header 已包含在内。
在下面的示例中,如果我忘记包含包含 FOO 定义的 header 文件,编译器将打印 "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
行,以便同时检查布尔值并在以下情况下生成错误FOO
未定义。
这样做的目的是让开发人员知道他们的代码应该包含
SPECIAL_MACRO(FOO)
同时检查 FOO 的布尔值,就好像它是 #if FOO
语句一样,并防止它们忘记包含 header 定义 FOO
.
维护大型代码库的同事(嗨,Hartmut,Kurt)完全使用 #define
s 运行 配置了相同的问题。一个简单的拼写错误(可能在 make 文件中)可能会导致难以追踪的细微错误。他们的解决方案:使用函数宏!在
#if SOME_COND()
// ...
#endif
如果 SOME_COND() 未定义,编译器会报错,这与简单的 SOME_COND 相反,如果未定义,它将被 0 替换。我喜欢它,因为它可用于 t运行 支持多个值,而不会因额外的 #ifdef
s.
而使代码混乱
我认为可以通过简单棘手的解决方案解决您的问题。我如下更改您的代码,我的代码理解 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 值。您应该为 header 缺席留零 situation.instead 您必须使用大于零的值(1、2、3、...)。
Foo==0 缺席情况。
Foo==1 配置 1.
Foo==2 配置2.
.
.
.
公认的使用 function-macros 的答案很好,但是如果您想保留普通宏 - 并且仍然使用 FOO 的值(如果已定义)并生成错误,否则您可以这样做:
#if FOO / defined(FOO)
#else
#endif
如果未定义 FOO
,它将触发整数除以零。
使用 -Wundef
gcc preprocessor option? This will only generate a warning, which can easily be turned to an error with -Werror=undef
怎么样?
宏 CHECK(x)
将:
- 如果宏
x
未定义则失败,
- 如果
x
定义为 0
,则计算为 00
- 如果
x
定义为 1
,则计算为 01
$ cat main.cpp
#define CAT(x, y) x##y
#define CHECK(x) CAT(0, x)
// usage
#define COND0 0
#define COND1 1
#if CHECK(COND)
#endif
#if CHECK(COND0)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
#if CHECK(COND1)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
$ g++ main.cpp
main.cpp:9:1: error: user-defined literal in preprocessor expression
9 | #if CHECK(COND)
| ^~~~~
main.cpp:15:17: note: ‘#pragma message: defined 0’
15 | #pragma message "defined 0"
| ^~~~~~~~~~~
main.cpp:19:17: note: ‘#pragma message: defined 1’
19 | #pragma message "defined 1"
| ^~~~~~~~~~~
我有几个配置文件,每个配置文件都包含一些布尔宏的定义,设置为 0 或 1。然后,在我的代码中,我检查这样一个宏的值来决定代码的哪一部分启用。现在是棘手的部分:我想确保包含我的宏定义的 header 已包含在内。
在下面的示例中,如果我忘记包含包含 FOO 定义的 header 文件,编译器将打印 "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
行,以便同时检查布尔值并在以下情况下生成错误FOO
未定义。
这样做的目的是让开发人员知道他们的代码应该包含
SPECIAL_MACRO(FOO)
同时检查 FOO 的布尔值,就好像它是 #if FOO
语句一样,并防止它们忘记包含 header 定义 FOO
.
维护大型代码库的同事(嗨,Hartmut,Kurt)完全使用 #define
s 运行 配置了相同的问题。一个简单的拼写错误(可能在 make 文件中)可能会导致难以追踪的细微错误。他们的解决方案:使用函数宏!在
#if SOME_COND()
// ...
#endif
如果 SOME_COND() 未定义,编译器会报错,这与简单的 SOME_COND 相反,如果未定义,它将被 0 替换。我喜欢它,因为它可用于 t运行 支持多个值,而不会因额外的 #ifdef
s.
我认为可以通过简单棘手的解决方案解决您的问题。我如下更改您的代码,我的代码理解 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 值。您应该为 header 缺席留零 situation.instead 您必须使用大于零的值(1、2、3、...)。
Foo==0 缺席情况。
Foo==1 配置 1.
Foo==2 配置2.
.
.
.
公认的使用 function-macros 的答案很好,但是如果您想保留普通宏 - 并且仍然使用 FOO 的值(如果已定义)并生成错误,否则您可以这样做:
#if FOO / defined(FOO)
#else
#endif
如果未定义 FOO
,它将触发整数除以零。
使用 -Wundef
gcc preprocessor option? This will only generate a warning, which can easily be turned to an error with -Werror=undef
怎么样?
宏 CHECK(x)
将:
- 如果宏
x
未定义则失败, - 如果
x
定义为0
,则计算为 - 如果
x
定义为1
,则计算为
00
01
$ cat main.cpp
#define CAT(x, y) x##y
#define CHECK(x) CAT(0, x)
// usage
#define COND0 0
#define COND1 1
#if CHECK(COND)
#endif
#if CHECK(COND0)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
#if CHECK(COND1)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
$ g++ main.cpp
main.cpp:9:1: error: user-defined literal in preprocessor expression
9 | #if CHECK(COND)
| ^~~~~
main.cpp:15:17: note: ‘#pragma message: defined 0’
15 | #pragma message "defined 0"
| ^~~~~~~~~~~
main.cpp:19:17: note: ‘#pragma message: defined 1’
19 | #pragma message "defined 1"
| ^~~~~~~~~~~