预编译阶段如何正确比较字符串?
预编译阶段正确比较字符串的方法
先明确问题根源:
- 第一种写法编译失败,是因为预处理器的
#if指令不支持直接比较字符串字面量,它只能处理整数常量表达式。 - 第二种写法判断始终为真,是因为
hello和asdasd都是未定义的标识符,预处理器会把未定义的标识符默认当作0,所以0 == 0永远成立。
下面给出两种可行的正确实现方式:
方案1:用整数常量映射字符串(最推荐)
把字符串对应的逻辑用唯一整数常量代替,预处理器可以直接高效地比较整数:
#include <iostream> // 给每个字符串定义对应的整数常量 #define STR_TYPE_HELLO 1 #define STR_TYPE_ASDASD 2 // 定义当前宏对应的整数 #define MY_MACRO STR_TYPE_HELLO int main() { #if MY_MACRO == STR_TYPE_ASDASD std::cout << "The macro is not equal to hello" << std::endl; #else std::cout << "The macro is equal to hello" << std::endl; #endif return 0; }
这种方式是预编译条件判断的常规操作,简单可靠,没有宏展开的坑。
方案2:利用预处理器字符串化特性(保留字符串定义场景)
如果必须保留字符串的原始定义,可以借助预处理器的字符串化(#)和宏展开特性,通过辅助宏实现比较:
#include <iostream> // 不带引号定义宏内容 #define MY_MACRO hello // 辅助宏:先展开宏再字符串化(必须分两层,否则宏不会先展开) #define STRINGIZE(x) #x #define STRINGIZE_EXPAND(x) STRINGIZE(x) // 目标字符串 #define TARGET_STRING "hello" int main() { #if STRINGIZE_EXPAND(MY_MACRO) == TARGET_STRING std::cout << "The macro is equal to hello" << std::endl; #else std::cout << "The macro is not equal to hello" << std::endl; #endif return 0; }
这里的关键是STRINGIZE_EXPAND的两层宏:先把MY_MACRO展开成hello,再用STRINGIZE把它转为字符串"hello",这样就能和目标字符串在预编译阶段正确比较。
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

