1

While working through a C++ book I came across an example that was comparing two strings using >. I played around with the code and found that these two statements do not evaluate to the same thing. Could someone explain what is happening when using < or > on strings in C++?

string s = "fool"; 
cout << ("fool" < "ape"); // returns true (1)
cout << (s < "ape"); //returns false (0)
  • Possible duplicate of [Using the less than comparison operator for strings](https://stackoverflow.com/questions/13829434/using-the-less-than-comparison-operator-for-strings) – RedShirt Jan 14 '19 at 02:51
  • 2
    `"fool"` is a character array rather than a `string` , this is a holdover from C. You can use `"fool"s` in modern C++ which is actually a `string`. – M.M Jan 14 '19 at 02:52
  • 1
    @JohnnyWineShirt: It's not a duplicate, because that one only discusses the case where a `std::string` is involved. Here the confusing case has no `std::string`, which is creating the problem. – Ben Voigt Jan 14 '19 at 02:52

3 Answers3

8

"fool" and "ape" are string literals and their type is a built-in type (array of const char, actually), so you get the built-in definition of operator<. Specifically, you get array-to-pointer decay, followed by pointer comparison.

Pointer comparison between items in different arrays is forbidden, so the comparison has an unspecified result (it may even not be repeatable).

The other comparison, s < "ape", is very different. One of the operands has class type, so an overloaded operator provided by std::string is used. That overload actually knows about string comparison.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
2
cout << (s < "ape"); //returns false (0)

This means you have converted (explicitly and implicitly) to string then you could compare safely.

cout << ("fool" < "ape"); // returns true (1)

This means you are comparing two pointers since they are string literals. Please see more about this at C++ Comparison of String Literals.

duong_dajgja
  • 4,196
  • 1
  • 38
  • 65
1

cout << ("fool" < "ape"); // returns true (1)

It compares the pointer addresses, it is unspecified which one is larger. If you write another program, the result may be false (0). Such code should never appear in your program. (Thanks to Ben Voigt, please refer to his answer)

cout << (s < "ape"); //returns false (0)

It uses C++'s overloaded operator of <, it compares the strings byte by byte.

shawn
  • 4,305
  • 1
  • 17
  • 25
  • 2
    It is even worse than "not determined which one is larger". Because the two pointers aren't from the same array or full object, it's actually undefined behavior. – Ben Voigt Jan 14 '19 at 02:51
  • Oops, a newer version of the Standard actually changed it from undefined behavior to merely unspecified result. – Ben Voigt Jan 14 '19 at 02:59
  • :D . Well, it is reasonable. IMO, if we try to compare two `const char *`, it can have some unspecified result. – shawn Jan 14 '19 at 03:03