https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99181

            Bug ID: 99181
           Summary: char_traits<char> (and thus string_view) compares
                    strings differently in constexpr and non-constexpr
                    contexts
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: richardpku at gmail dot com
  Target Milestone: ---

Minimal program to produce bug (run it on a platform where char is a signed
type, such as i386/x86-64):

/tmp % cat a.cpp
#include <string_view>
#include <iostream>

using namespace std;

int main() {
        // constexpr
        constexpr bool i = ("\xff"sv > "aaa"sv);
        cout << i << ",";

        // not constexpr
        auto a = "\xff"sv, b = "aaa"sv;
        cout << (a > b) << endl;

        return 0;
}
/tmp % g++ -std=gnu++2a a.cpp && ./a.out
0,1

The expected result is "1,1".


In a non-constexpr context, std::char_traits<char>::compare invokes
__builtin_memcmp, which is required by C standard to interpret characters as
unsigned char.

In a constexpr context, however, std::char_traits<char>::compare invokes
__gnu_cxx::char_traits<char>::compare, which in turn calls
__gnu_cxx::char_traits<char>::lt to compare chars.
__gnu_cxx::char_traits<char>::lt (unlike std::char_traits<char>::lt) is not
specialized to compare chars as unsigned char.

Reply via email to