lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Arithmetic on enums in C++20


From: Vadim Zeitlin
Subject: Re: [lmi] Arithmetic on enums in C++20
Date: Mon, 8 Nov 2021 22:45:22 +0100

On Mon, 8 Nov 2021 18:03:46 +0000 Greg Chicares <gchicares@sbcglobal.net> wrote:

GC> Vadim--debian "bookworm" has upgraded its g++ to version 11, and
GC> now, in some proprietary code whose sole purpose is to generate
GC> product-database files, diagnostics like this occur:
GC> 
GC> /opt/lmi/src/lmi/../products/src/my_db.cpp:3998:39: error: arithmetic 
between different enume
GC> ration types 'mcenum_uw_basis' and 'enum_database_dimensions' is deprecated 
[-Werror=deprecat
GC> ed-enum-enum-conversion]
GC>  3998 |     v[mce_s_FL + mce_simplified_issue * e_max_dim_state] = 
REDACTED::policy_form_REDACTED_FL_SimpUw;
GC>       |                  ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~

 Yes, this is, unfortunately, a rather annoying consequence of upgrading
the existing code bases to C++20. In principle, this is, of course, a good
warning, but in practice I haven't found any code where this warning would
have pointed out a real problem , but did find hundreds of false positives.

GC> Of course I don't want to suppress the compiler diagnostic
GC> with a '-Wno-whatever' option.

 I didn't want to do it for various wx enums that are meant to be combined
willy-nilly with each other, so my solution was to add a special
wxALLOW_COMBINING_ENUMS macro, see

https://github.com/wxWidgets/wxWidgets/commit/3d278ee75fa#diff-e391c490e46ded5849800b8de65d0a1ea24e9b75bb38d2714a6a786a2d4a51f9R1258

I don't think it's a good solution for this particular problem, even if it
could be used here too (in a modified form, i.e. by defining an overloaded
operator*() rather than operators "+" and "|"), but it might come in handy
for the other cases, if you ever really want to allow combining the values
from different enums together.

GC> The diagnostic goes away if I replace 'e_max_dim_state' with its
GC> numeric value:
GC> 
GC> - mce_s_FL + mce_simplified_issue * e_max_dim_state
GC> + mce_s_FL + mce_simplified_issue * 53
GC> 
GC> so my first thought is to replace the enum above with:
GC>   constexpr int e_max_dim_state {53};
GC> and so on. That seems righteous to me: whereas 'mcenum_state'
GC> is a genuine type that could be used for a function argument,
GC> 'enum_database_dimensions' isn't never used in any such way:
GC> it's just a set of constants that are grouped together for
GC> convenience, and the enum might as well be anonymous.

 If there is nothing requiring these constants to have a common type, I
agree that using "constexpr int" for them is a good/better approach.

GC> But am I missing something? I had guessed that the expression
GC>   mce_s_FL + mce_simplified_issue * 53
GC> would still elicit the same diagnostic, but at '+' instead
GC> of at '*', because the types differ:
GC> 
GC>   mcenum_state  +    mcenum_uw_basis    *  int
GC>   mce_s_FL      + mce_simplified_issue  *  53
GC>                 ^ here's where I expected a diagnostic
GC> 
GC> and addition is as surely "arithmetic" as is multiplication.

 I haven't tested this, but I am almost sure that the reason you don't get
the warning here is that the result of multiplying an enum by an int is an
int, due to the usual type promotion rules, and adding enums and ints is
still allowed. If you removed this "* 53", you would almost certainly get
the warning you expect.

GC> Is the long-term vision of C++ to deprecate all arithmetic
GC> on enums?

 I believe all of it is already deprecated. Whether it will be actually
removed is less clear, but considering that just about non-trivial code
base which I tried compiling with C++20 compilers had at least some
instances of this warning, it probably won't happen any time soon.

 Regards,
VZ

Attachment: pgp3TFj2FkUTG.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]