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:
Expand|Select|Wrap|Line Numbers
- g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Expand|Select|Wrap|Line Numbers
- //
- // 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;
- }
Expand|Select|Wrap|Line Numbers
- 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);
- | ~~~~~^~~~~
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