[Bug c++/52763] New: Warning if compare between enum and non-enum type

2012-03-29 Thread gccrepo...@gmx-topmail.de
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52763

 Bug #: 52763
   Summary: Warning if compare between enum and non-enum type
Classification: Unclassified
   Product: gcc
   Version: 4.6.3
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: gccrepo...@gmx-topmail.de


Hi, 

the following program doesn't create a warning. It would be nice to get an
warning each time a enumeration type is compared to a non enumeration type,
because it forces better readable code (at least in my opinion).

I compiled this with 'g++ -Wall -Wextra -Wconversion -Werror'.

Best regards,
  Mikka


typedef enum {
  NONE = 0, ONE = 1, TWO = 2
} tEnumType;

int main(void){
  tEnumType var1 = TWO;
  //Warn here, because we compare an enum to a non-enum type (1)
  //should be 'if (var1 == ONE)'
  if (var1 == 1)
return 1;
  else
return 0;
}


[Bug c++/52763] Warning if compare between enum and non-enum type

2012-04-04 Thread gccrepo...@gmx-topmail.de
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52763

Mikka  changed:

   What|Removed |Added

 Target||x86_64
   Host||Fedora 16
  Build||20120306

--- Comment #1 from Mikka  2012-04-04 13:03:00 UTC 
---
Warning is also missing in 4.7.0 (Debian 4.7.0-1)


[Bug c++/52763] Warning if compare between enum and non-enum type

2012-04-04 Thread gccrepo...@gmx-topmail.de
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52763

--- Comment #3 from Mikka  2012-04-04 14:22:45 UTC 
---
(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).
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.


[Bug c++/52763] Warning if compare between enum and non-enum type

2012-04-16 Thread gccrepo...@gmx-topmail.de
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52763

--- Comment #5 from Mikka  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.