When comparing a string literal with another string literal with the ==
operator (or !=
), is the result well defined?
For example, are the following guaranteed to hold?
assert("a" == "a");
assert("a" != "b");
Please don't say stuff like "use std::string" instead. I just want to know this specific case.
"a" == "a"
This expression may yield true
or false
; there are no guarantees. The two "a"
string literals may occupy the same storage or they may exist at two different locations in memory.
I think that the closest language in the C++ Standard is: "Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation defined" (C++11 §2.14.5/12). There are no other requirements or restrictions, so the result is left unspecified.
"a" != "b"
This expression must yield false
because there is no way that these two string literals can occupy the same location in memory: "a"[0] != "b"[0]
.
When you compare string literals in this way, you are really comparing the pointers to the initial elements in the arrays.
Because we are comparing pointers, the relational comparisons (<
, >
, <=
, and >=
) are even more problematic than the equality comparisons (==
and !=
) because only a restricted set of pointer comparisons may be performed using the relational comparisons. Two pointers may only be relationally compared if they are both pointers into the same array or pointers into the same object.
If the two "a"
string literals occupy the same location in memory, then "a" < "a"
would be well-defined and would yield false
, because both pointers point to the initial element ('a'
) of the same array.
However, if the two "a"
string literals occupy different locations in memory, the result of "a" < "a"
is undefined, because the two pointers being compared point into entirely unrelated objects.
Because "a"
and "b"
can never occupy the same location in memory, "a" < "b"
always has undefined behavior. The same is true for the other relational comparison operators.
If you did, for some reason, want to relationally compare two string literals and have well-defined results, you can use the std::less
comparer, which provides a strict-weak ordering over all pointers. There are also std::greater
, std::greater_equal
, and std::less_equal
comparers. Given that string literals with the same contents may not compare equal, I don't know why one would ever want to do this, but you can.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With