On Thu, 22 Apr 2021 at 15:59, Martin Sebor <mse...@gmail.com> wrote:
>
> On 4/22/21 2:52 AM, Jonathan Wakely wrote:
> > On Thu, 22 Apr 2021, 08:47 Martin Liška, wrote:
> >
> >     On 4/21/21 6:11 PM, Martin Sebor wrote:
> >      > On 4/21/21 2:15 AM, Martin Liška wrote:
> >      >> Hello.
> >      >>
> >      >> It's addressing the following Clang warning:
> >      >> cp/lex.c:170:45: warning: result of comparison of constant 64
> >     with expression of type 'enum ovl_op_code' is always true
> >     [-Wtautological-constant-out-of-range-compare]
> >      >>
> >      >> Patch can bootstrap on x86_64-linux-gnu and survives regression
> >     tests.
> >      >>
> >      >> Ready to be installed?
> >      >> Thanks,
> >      >> Martin
> >      >>
> >      >> gcc/cp/ChangeLog:
> >      >>
> >      >>     * cp-tree.h (STATIC_ASSERT): Prefer static assert.
> >      >>     * lex.c (init_operators): Remove run-time check.
> >      >> ---
> >      >>   gcc/cp/cp-tree.h | 3 +++
> >      >>   gcc/cp/lex.c     | 2 --
> >      >>   2 files changed, 3 insertions(+), 2 deletions(-)
> >      >>
> >      >> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> >      >> index 81ff375f8a5..a8f72448ea9 100644
> >      >> --- a/gcc/cp/cp-tree.h
> >      >> +++ b/gcc/cp/cp-tree.h
> >      >> @@ -5916,6 +5916,9 @@ enum ovl_op_code {
> >      >>     OVL_OP_MAX
> >      >>   };
> >      >>   +/* Make sure it fits in lang_decl_fn::operator_code. */
> >      >> +STATIC_ASSERT (OVL_OP_MAX < (1 << 6));
> >      >> +
> >      >
> >      > I wonder if there's a way to test this directly by something like
> >      >
> >      >   static_assert (number-of-bits (ovl_op_info_t::ovl_op_code)
> >      >                  <= number-of-bits (lang_decl_fn::operator_code));
> >
> >     Good point, but I'm not aware of it. Maybe C++ people can chime in?
> >
> >
> > ovl_op_code is an unscoped enumeration (meaning "enum" not "enum class")
> > with no fixed underlying type (i.e. no enum-base like ": int" or ":
> > long" is specified) which means that the number of bits in is value
> > representation is the number of bits needed to represent the minimum and
> > maximum enumerators:
> >
> > "the values of the enumeration are the values representable by a
> > hypothetical integer type with minimal width M such that all enumerators
> > can be represented."
> >
> > There is no function/utility like number-of-bits that can tell you that
> > from the type though.You could use
> > std::underlying_type<ovl_op_code>::type to get the integral type that
> > the compiler used to represent it, but that will probably be 'int' in
> > this case and so all it tells you is an upper bound of no more than 32
> > bits, which is not useful for this purpose.
>
> I suspected there wasn't a function like that.  Thanks for confirming
> it.  I wrote the one below just to see if it could be done.  It works
> for one bit-field but I can't think of a way to generalize it.  We'd
> probably need a built-in for that.  Perhaps one might be useful.
>
> enum E { e = 5 };
> struct A { E e: 3; };
>
> constexpr int number_of_bits ()
> {
>    A a = { };
>    a.e = (E)-1;
>    int n = 0;
>    for (; a.e; ++n)
>      a.e = (E)((unsigned)a.e ^ (1 << n));
>    return n;
> }
>
> Martin

Or:

enum E { e = 5 };
struct A { E e: 3; };

constexpr int number_of_bits ()
{
   A a = { };
   a.e = (E)-1;
   return 32 - __builtin_clz(a.e);
}


But you can't get the number-of-bits needed for all the values of the
enum E, which is what I was referring to.

If you know the enumerators go from 0 to MAX (as is the case for
ovl_op_code) you can use (32 - __builtin_clz(MAX)) there too, but in
the general case you don't always know the maximum enumerator without
checking, and it depends whether the enumeration has a fixed
underlying type.

Reply via email to