当使用==
运算符(或者!=
)比较一个字符串字面值和另一个字符串字面值时,结果是否是良好定义的?
例如,以下内容是否保证成立?
assert("a" == "a");
assert("a" != "b");
请不要说像“使用std::string”这样的东西,我只想知道这个特定情况。
当使用==
运算符(或者!=
)比较一个字符串字面值和另一个字符串字面值时,结果是否是良好定义的?
例如,以下内容是否保证成立?
assert("a" == "a");
assert("a" != "b");
"a" == "a"
此表达式可能产生
true
或false
;这没有保证。这两个"a"
字符串字面量可能占用相同的存储空间,也可能存在于内存中的两个不同位置。我认为在C ++标准中最接近的语言是:“所有字符串文字是否不同(即存储在不重叠的对象中)由实现定义”(C ++11 §2.14.5 / 12)。没有其他要求或限制,因此结果未指定。
"a" != "b"
这个表达式必须返回
false
,因为这两个字符串字面值不可能占用同一内存位置:"a"[0] != "b"[0]
。
当以这种方式比较字符串字面值时,实际上是在比较数组中初始元素的指针。
由于我们正在比较指针,因此关系比较运算符(
<
、>
、<=
和>=
)比相等性比较运算符(==
和!=
)更具问题性,因为只有一组受限制的指针比较可以使用关系比较运算符进行。只有两个指针都指向同一个数组或同一对象时,它们才能进行关系比较。如果两个字符串字面值
"a"
在内存中占据相同位置,则"a" < "a"
将是完全定义的并返回false
,因为两个指针均指向同一数组的初始元素('a'
)。但是,如果两个字符串字面值
"a"
在内存中占据不同位置,则"a" < "a"
的结果是未定义的,因为被比较的两个指针指向完全无关的对象。由于
"a"
和"b"
永远不可能占用同一内存位置,"a" < "b"
始终具有未定义行为。其他关系比较运算符也是如此。如果出于某种原因,您想要对两个字符串字面值进行关系比较,并且需要定义良好的结果,则可以使用
std::less
比较器,它在所有指针上提供了严格弱排序。虽然相同内容的字符串字面值可能不相等,但我不知道为什么会有人这样做,但您可以这样做。
std::less
及其相关内容,那就太好了。 - Cheers and hth. - Alfassert(!strcmp("a", "a"))
。或者,您可以使用某种基于constexpr的strcmp进行静态断言:constexpr bool static_strequal_helper(const char * a, const char * b, unsigned len) {
return (len == 0) ? true : ((*a == *b) ? static_strequal_helper(a + 1, b + 1, len - 1) : false);
}
template <unsigned N1, unsigned N2>
constexpr bool static_strequal(const char (&str1)[N1], const char (&str2)[N2]) {
return (N1 == N2) ? static_strequal_helper(&(str1[0]), &(str2[0]), N1) : false;
}
static_assert(static_strequal("asdf", "asdf"), "no error - strings are equal");
static_assert(static_strequal("asdf", "jkl;"), "strings are not equal");
assert(!strcmp("asdf", "jkl;")); //no compile error - runtime error
//cannot use strcmp in static assert as strcmp is not constexpr...
然后,使用g++ -std=c++0x(或gcc>= 4.7的-std=c++11)进行编译,然后...
error: static assertion failed: "strings are not equal"
assert(!"消息内容在这里");
。 - chris