Take the 2-minute tour ×

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.

share|improve this question
Why would you need to do this? For a guaranteed false, try assert (!"Message goes here"); –  chris Jun 21 '12 at 18:06
@chris: Curiosity for one. Also for an enum-like class implementation idea. –  Thomas Eding Jun 21 '12 at 18:07
possible duplicate of Output difference in gcc and turbo C –  kennytm Jun 21 '12 at 18:08
Implementation defined, afaik; as == compares the addresses of the const char* S . –  manasij7479 Jun 21 '12 at 18:08

2 Answers 2

up vote 13 down vote accepted
"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.

share|improve this answer
I think it would be nice if you could also discuss less-than comparisions, which are less well-defined, and std::øess & friends –  Cheers and hth. - Alf Jun 21 '12 at 18:14
@Cheersandhth.-Alf: Good idea; added. Also, I don't know if I've mentioned this, but I like how you've incorporated "Cheers and hth" into your name to work around the grumpier Stack Overflow contributors. ;-) –  James McNellis Jun 21 '12 at 18:34

The idea is that in C++ string literals are arrays. Since arrays do not have comparison operators defined for them, they are compared using the next best fit - the pointer comparison operator, as arrays will implicitly decay to pointers, so any comparison compares address and not content. Since "a" and "b" cannot be at the same memory location, "a" != "b" is a true assertion. It also forms a valid static assertion. No such guarantee can be made about "a" == "a", though GCC with -fmerge-constants (implied at -O1) can make a reasonably strong probability and -fmerge-all-constants can give you a guarantee (that potentially results in non-conforming behavior).

If you happen to want a content-based comparison, you can always use assert(!strcmp("a", "a")). Or, you can use some sort of constexpr based strcmp for a static assertion:

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

Then, compile with g++ -std=c++0x (or -std=c++11 for gcc >= 4.7), and...

error: static assertion failed: "strings are not equal"
share|improve this answer

Your Answer


