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

Reply via email to