为什么在A
和B
不同的情况下,以下代码中的std::cout
行仍然可以运行?
#include <iostream>
enum T { A = 1, B = 2 };
// #define A 1
// #define B 2
int main() {
#if (A == B)
std::cout << A << B;
#endif
}
如果我使用#define
(注释掉了),我不会得到我所期望的输出。
问题的原因:
我想为一些测试代码提供一个模式选择器,在这个模式选择器中,我可以通过注释/取消注释顶部的行来轻松地更改模式:
enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 };
// #define MODE MODE_RGB
#define MODE MODE_GREY
// #define MODE MODE_CMYK
int main() {
#if (MODE == MODE_RGB)
// do RGB stuff
#elif (MODE == MODE_GREY)
// do greyscale stuff
#else
// do CMYK stuff
#endif
// some common code
some_function(arg1, arg2,
#if (MODE == MODE_RGB)
// RGB calculation for arg3,
#elif (MODE == MODE_GREY)
// greyscale calculation for arg3,
#else
// CMYK calculation for arg3,
#endif
arg4, arg5);
}
我知道我可以使用数字值,例如
#define MODE 1 // RGB
...
#if (MODE == 1) // RGB
但这会降低代码的可读性。
有没有一个优雅的解决方案呢?
发布于 2016-01-08 20:34:09
没有名为A
或B
的宏,因此在您的#if
行中,A
和B
将被0
替换,因此您实际上拥有:
enum T { A = 1, B = 2 };
int main() {
#if (0 == 0)
std::cout << A << B;
#endif
}
在编译器了解您的enum
之前,预处理器就会运行。预处理器只知道宏(#define
)。
发布于 2016-01-08 20:31:55
这是因为预处理器在编译前工作。
由于枚举定义发生在编译时,因此A和B在预处理时都被定义为空(pp- 0
),因此相等,因此输出语句包含在编译后的代码中。
当您使用#define
时,它们在预处理时的定义不同,因此语句的计算结果为false。
关于你想要做什么的评论,你不需要使用预处理器#if
来做这件事。您可以只使用标准if
,因为MODE
和MODE_GREY
(或MODE_RGB
或MODE_CMYK
)都仍然是已定义的:
#include <iostream>
enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 };
#define MODE MODE_GREY
int main()
{
if( MODE == MODE_GREY )
std::cout << "Grey mode" << std::endl;
else if( MODE == MODE_RGB )
std::cout << "RGB mode" << std::endl;
else if( MODE == MODE_CMYK )
std::cout << "CMYK mode" << std::endl;
return 0;
}
只使用预处理器的另一个选项是@TripeHound correctly answered below。
发布于 2016-01-08 20:34:07
在条件预处理器指令中,未定义宏的标识符被解释为值0。因此,由于您没有定义宏A
和B
,因此它们都被认为是0,并且两个0彼此相等。
未定义(对于预处理器)标识符被视为0的原因是因为它允许在条件中使用未定义的宏,而不使用#ifdef
。
https://stackoverflow.com/questions/34677148
复制相似问题