C++ Logo

SG12

Advanced search

Subject: Re: [isocpp-core] New Issue?: [class.bit] p.4 - silent UB and necessary restriction?
From: Tim Song (t.canens.cpp_at_[hidden])
Date: 2021-02-05 08:06:38


On Fri, Feb 5, 2021 at 7:55 AM Peter Sommerlad (C++)
<peter.cpp_at_[hidden]> wrote:
>
> 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

This doesn't follow. UB by omission only applies when nothing in the
whole standard defines behavior; in this case the behavior is defined
by the usual rules for == and l-to-r conversion.

>
> 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