Problem With Comparison Operator <=> in G++

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Oralloy
    Recognized Expert Contributor
    • Jun 2010
    • 988

    Problem With Comparison Operator <=> in G++

    Hello folks,
    I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
    The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
    This is as boiled down as I can make it.
    Here is my compilation command:
    Code:
    g++-12 -std=c++20 -Wnarrowing bit_field.cpp
    Here is the code in bit_field.cpp:
    Code:
    //
    //  bit_field.cpp
    //  - demonstrate problem with bit field comparisons
    //
    
    #include <cstdint>
    #include <iostream>
    
    struct thing_t
    {
      ::std::uint32_t value : 4;
      auto operator<=>(thing_t const &that) const
      {
        return  (this->value <=> that.value);
      }
    };
    
    int main()
    {
      thing_t s0{1};
      thing_t s1{2};
    
      ::std::cout
        << ::std::boolalpha
        << "s0 -- s1 ? " << ((s0 <=> s1) == 0) << "\n";
    
      return 0;
    }
    And, here are the errors which I see:
    Code:
    bit_field.cpp: In member function ‘auto thing_t::operator<=>(const thing_t&) const’:
    bit_field.cpp:14:20: warning: narrowing conversion of ‘((const thing_t*)this)->thing_t::value’ from ‘const uint32_t’ {aka ‘const unsigned int’} to ‘int’ [-Wnarrowing]
       14 |     return  (this->value <=> that.value);
          |              ~~~~~~^~~~~
    bit_field.cpp:14:35: warning: narrowing conversion of ‘that.thing_t::value’ from ‘const uint32_t’ {aka ‘const unsigned int’} to ‘int’ [-Wnarrowing]
       14 |     return  (this->value <=> that.value);
          |                              ~~~~~^~~~~
    Needless to say, I am confused.
    My understanding from what I have read is that "value" would be promoted to a fully unsigned int32_t value, which ought be comparable to another of the same type.
    My gut reaction is that I have encountered a compiler bug, however I have found only a few in my career, so likely not.
    Obviously I have done something stupid, as I can usually read multiple sources of documentation and ascertain where I encroached into undefined behaviour.
    Can any of you provide explanatory links or enlighten me?
    Thank You,
    Oralloy
Working...