有没有办法让C预处理器解析#error语句中的宏?

Mad*_*dio 11 c++ c-preprocessor

正如标题所说.我想在#error语句的文本中使用预处理器宏:

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #error "SOME_MACRO was not 0; it was [value of SOME_MACRO]"
#endif
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我希望预处理器解析[value of SOME_MACRO]为实际值SOME_MACRO,在这种情况下为1.这应该在预处理器,编译器或任何进程之前发生#error打印错误输出
有没有办法做到这一点或者这不是可能?

我不想知道是否有ISO C++标准方法可以做到这一点,因为afaik预处理器指令#error没有在任何ISO C++标准中声明.但是,我知道GCC和Visual C++的支持#error.但我的问题不是那些编译器特有的,我只是好奇,如果有任何C/C++编译器/预处理器可以做到这一点.

我试图搜索那个话题,但没有任何运气.

Kir*_*sky 5

在Visual Studio中,您可以使用pragmamessage如下:

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #pragma message ( "SOME_MACRO was not 0; it was " STRING(SOME_MACRO) )
    #error SOME_MACRO was not 0;
#endif
Run Code Online (Sandbox Code Playgroud)

这将生成两条消息,但您将获得值SOME_MACRO.在G ++中使用以下代码(来自注释:g ++版本4.3.4适用于上面的代码中的括号):

#pragma message "SOME_MACRO was not 0; it was " STRING(SOME_MACRO)
Run Code Online (Sandbox Code Playgroud)

  • 有趣,有用.谢谢!如果你在那里有`#pragma`,你当然也需要`#error`,如果编译器不识别pragma,它会忽略它 - 它只是稍微降低了诊断,但是你'在这种情况下,你做得最好.此外,括号版本在G ++中工作,因此您可以在MSVC和G ++中使用相同的机制.有趣的是,GCC 4.6.0(与G ++相对)似乎忽略了`#pragma message`. (3认同)

Fle*_*exo 5

为了完整性我建议的C++ 0x方式(使用与Kirill相同的技巧):

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#define EXPECT(v,a) static_assert((v)==(a), "Expecting " #v "==" STRING(a) " [" #v ": "  STRING(v) "]")


#define VALUE 1

EXPECT(VALUE, 0);
Run Code Online (Sandbox Code Playgroud)

得到:

g++ -Wall -Wextra -std=c++0x test.cc                     
test.cc:9: error: static assertion failed: "Expecting VALUE==0 [VALUE: 1]"
Run Code Online (Sandbox Code Playgroud)

  • 更喜欢`(v)==(a)` (2认同)