I was going through my code for finding suffix arrays and decided to change the dollar character (a character with small value, which is appended to the end of the string in many implementations) to std::numeric_limits<char>::min()
hoping it won't change the program's behaviour.
Interestingly, it did.
This is what I found out:
#include <iostream>
#include <limits>
int main() {
std::cout << (std::numeric_limits<char>::min() < 'a' ? "Yes" : "No") << '\n';
std::string s1, s2;
s1 += std::numeric_limits<char>::min();
s2 += 'a';
std::cout << (s1 < s2 ? "Yes" : "No") << '\n';
std::cout << int(s1[0]) << ' ' << int(s2[0]) << '\n';
}
Program Output:
Yes
No
-128 97
I have no idea why std::string
behaves like this. I ran this program on MinGW, MSVC and Clang and got the same output every time.
The
<
operator to compare strings internally callschar_traits<char>::compare
, which callschar_traits<char>::lt
. If you try comparing the charactersstd::numeric_limits<char>::min()
and'a'
withchar_traits<char>::lt
, you will find out that'a'
is smaller. Indeed, the C++ reference tells us (if you choose C++11) that:So even though comparing characters with
<
does signed comparison, comparing strings with<
compares the characters in the unsigned way.Thanks! That was very helpful!