http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52763

--- Comment #5 from Mikka <gccrepo...@gmx-topmail.de> 2012-04-16 11:01:25 UTC 
---
(In reply to comment #4)
> (In reply to comment #3)
> > (In reply to comment #2)
> > > But what about cases such as (val1 == (ONE|TWO)) ?
> > > 
> > > (ONE|TWO) is of type 'int' but that code is correct and shouldn't warn
> > 
> > In my opinion, there should be a warning here, because (ONE|TWO) is not in 
> > the
> > enumeration range (there is no definition for 3).
> 
> It is in range.  For enum { NONE = 0, ONE = 1, TWO = 2 } the standard says the
> values of the enumeration are in the range 0 to 3, e.g. it could be 
> represented
> by a two-bit unsigned integer.  The standard sets the rules, not your opinion
> :)
> 
While the standard says, it should be an integer of this range. It does not
say, that the enumeration-type should be able/used to store other values as the
ones, which are defined. Actually it does say, that there is not conversion
from int to enum. So this means here, that we would compare the enum to an
integer with a value, which we shouldn't be able to store in the enumeration in
the first place. "var = 1;" produces as expected an error, "invalid conversion
from ‘int’ to ‘tEnumType’".

> Also, that would warn for perfectly valid (and very common) uses of 
> enumeration
> types for bitmasks, e.g. std::ios::openmode could be defined as an enumeration
> type and you could say
> 
>    if (mode == (std::ios::in|std::ios::out))
> 
> where there is no enumerator defined for in|out, but this code is common and
> should not warn.
> 
Just because it is common, it doesn't mean that it's perfect. In my opinion
this is an abuse of the enumeration here. If this is a bitmask, it should be
implemented this way, using either the c-style unions or c++ bitsets or 
something else (custom class, ...). The name enumeration means we are counting
something, not a bitmask.

E.g. "mode = (std::ios::in|std::ios::out)" only works, because the function "|"
is defined using static_cast. For me this is quite a hint, that it's quite not
perfect, but more an abuse.
> > If it was defined (e.g. typedef enum {NONE = 0, ONE = 1, TWO = 2, THREE = 3}
> > tEnumType), result could again be of the enumeration type and there would 
> > be no
> > warning.
> 
> No, the result would still be an int, ONE|TWO has type int, period.
> 
> I think the warning could be useful in some cases, but it needs to be defined
> much more carefully than simply "warning each time a enumeration type is
> compared to a non enumeration type" as you suggested.
I still think the warning should be there in both cases. It shouldn't be a
default warning, as legacy code would produce too many warnings.

For my solution, from now on I will use "enum class", as it does exactly what I
want. While this is not my optimal solution (forcing at least gcc 4.4 for all
project attendees), it will work, somehow.

Reply via email to