ShubhamAvasthi's blog

By ShubhamAvasthi, history, 4 years ago, In English

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.

  • Vote: I like it
  • +61
  • Vote: I do not like it

»
4 years ago, # |
  Vote: I like it +52 Vote: I do not like it

The < operator to compare strings internally calls char_traits<char>::compare, which calls char_traits<char>::lt. If you try comparing the characters std::numeric_limits<char>::min() and 'a' with char_traits<char>::lt, you will find out that 'a' is smaller. Indeed, the C++ reference tells us (if you choose C++11) that:

In the standard specializations of char_traits, this function behaves as the built-in operator< for type unsigned char.

So even though comparing characters with < does signed comparison, comparing strings with < compares the characters in the unsigned way.