C/C++中赋值为字符串字面量的const char*用==比较是否安全
直接用
==比较字符串字面量指针的安全性结论 这种写法不符合C语言标准的可移植性要求,不属于安全写法,不建议使用。
- 从C语言标准的规定来看,标准从未强制要求内容相同的字符串字面量必须存储在同一内存地址。标准仅说明编译器可以对相同的字符串字面量做去重合并,是否合并完全是编译器的实现选择:哪怕在同一个源码文件里写两次内容完全一致的字符串字面量,编译器完全可以把它们存在两个不同的地址,这时候用
==比较就会判定为不相等,出现逻辑错误。 - 跨编译单元的场景下行为更不可控:如果相同内容的字符串字面量写在两个不同的
.c源文件里,是否会在链接阶段被合并,完全取决于编译器、链接器的配置参数。比如GCC开启-fmerge-constants选项时会做跨单元合并,关闭该选项就不会;MSVC的默认配置下通常不会合并跨编译单元的同内容字符串字面量,这时候直接比指针必然出错。 - 这种写法没有任何维护容错性:你当下能保证所有赋值都用字符串字面量,后续代码迭代中只要有一次给
type成员赋了非字面量的字符串(比如栈上字符数组、堆上动态分配的字符串),哪怕内容完全匹配,==比较也会得到错误结果,这类问题排查成本极高。
针对你提到的性能优化诉求,完全没必要靠赌编译器行为实现:
- 普通场景下直接用
strcmp即可,这类短类型标识的比较开销只有几个时钟周期,几乎不可能成为程序的性能瓶颈。- 真要追求极致的指针比较性能,可以统一定义全局唯一的类型标识常量,所有赋值都引用这些常量而非直接写裸字符串字面量,这种写法下指针比较是100%符合标准、完全安全的:
// 头文件中声明全局类型常量 extern const char * const TYPE_A; extern const char * const TYPE_B; // 单独的源文件中统一定义常量 const char * const TYPE_A = "TypeA"; const char * const TYPE_B = "TypeB"; // 赋值时统一使用常量,不直接写字面量 Foo bar, baz; bar.type = TYPE_A; baz.type = TYPE_A; // 此时用==比较完全安全 if (bar.type == baz.type) { printf("Same\n"); }
内容的提问来源于stack exchange,提问作者David Callanan
相关产品推荐
相关产品推荐

