如果未定义选中的布尔宏,则会生成错误

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)完全使用 #defines 运行 配置了相同的问题。一个简单的拼写错误(可能在 make 文件中)可能会导致难以追踪的细微错误。他们的解决方案:使用函数宏!

#if SOME_COND()
 // ...
#endif

如果 SOME_COND() 未定义,编译器会报错,这与简单的 SOME_COND 相反,如果未定义,它将被 0 替换。我喜欢它,因为它可用于 t运行 支持多个值,而不会因额外的 #ifdefs.

而使代码混乱

我认为可以通过简单棘手的解决方案解决您的问题。我如下更改您的代码,我的代码理解 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"
      |                 ^~~~~~~~~~~