C++ Logo

SG12

Advanced search

Subject: Re: [isocpp-core] New Issue?: [class.bit] p.4 - silent UB and necessary restriction?
From: Peter Sommerlad (C++) (peter.cpp_at_[hidden])
Date: 2021-02-05 07:55:55


Tim,

thanks.

let me consider an example:

enum color:unsigned long long{ black, red=1, blue=2, green=4};

struct A{
color bf:2; // could do black red and blue, but not green
color xf:6; // large enough for black red blue and green, but not
color(0x100000ULL)

};

What you wrote:

A a{};
a.bf = black: // should be OK value is 0

if (a.bf == black) // UB according to [class.bit]p.4

a.bf = green; // not big enough to represent 4! impl-def.

a.xf = green; // is this ok or UB?

if (a.xf == green) // is that UB? not all possible color values fit in 6
bits, only its enumerators.

The question is, what is "large enough to hold all values" when reading
from an enum bit field.

Regards
Peter.

Tim Song wrote on 05.02.21 13:52:
> [expr.ass]/4:
>
> When the left operand of an assignment operator is a bit-field that
> cannot represent the value of the expression, the resulting value of
> the bit-field is implementation-defined.
>
> I haven't checked if we say anything about what happens when you
> initialize a bit-field in this scenario, but the intent seems clear to
> me and it isn't undefined.
>
> On Fri, Feb 5, 2021 at 6:36 AM Peter Sommerlad (C++) via Core
> <core_at_[hidden]> wrote:
>>
>> Hi
>>
>> while discussing MISRA C++ rules wrt bit fields we came across the
>> following (slightly changed in C++20) sentence [class.bit] p.4:
>>
>> "If a value of an enumeration type is stored into a bit-field of the
>> same type and the width is large enough to hold all the values of that
>> enumeration type (9.7.1), the original value and the value of the
>> bit-field compare equal."
>>
>> This silently introduces UB, if the bit field is narrower as the
>> underlying type.
>>
>> For an enumeration type with a specified underlying type that by
>> definition can represent all of its values, does that mean a bit field
>> must not be shorter than the underlying type to make it useful. Or does
>> it mean, only the named enumerators can be stored to be no UB.
>>
>> struct{
>> std::byte a:4;
>> };
>>
>> can I ever access a and compare it with std::byte{0} ?
>>
>> Wouldn't it be useful to allow shorter bit fields for enumeration types
>> and allow values that fit to be taken out of the bitfield?
>>
>> Regards
>> Peter.
>>
>> --
>> Peter Sommerlad
>>
>> Better Software: Consulting, Training, Reviews
>> Modern, Safe & Agile C++
>>
>> peter.cpp_at_[hidden]
>> +41 79 432 23 32
>> _______________________________________________
>> Core mailing list
>> Core_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/core
>> Link to this post: http://lists.isocpp.org/core/2021/02/10474.php

-- 
Peter Sommerlad
Better Software: Consulting, Training, Reviews
Modern, Safe & Agile C++
peter.cpp_at_[hidden]
+41 79 432 23 32

SG12 list run by sg12-owner@lists.isocpp.org