Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ compare two string literals

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.

like image 657
Thomas Eding Avatar asked Jun 21 '12 18:06

Thomas Eding


1 Answers

"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.

like image 172
James McNellis Avatar answered Sep 28 '22 06:09

James McNellis