[Bug c++/58559] New: Underlying type of enum is hybrid of int and unsigned
cyp561 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Sat Sep 28 16:46:00 GMT 2013
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58559
Bug ID: 58559
Summary: Underlying type of enum is hybrid of int and unsigned
Product: gcc
Version: 4.7.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: cyp561 at gmail dot com
An enum with no values outside the range 0..INT_MAX seems to be treated as an
int in all cases, with the exception that casting to long or long long does not
sign extend. As far as I understand, the compiler is free to decide to use
either int or unsigned to represent an enum, but not some hybrid.
Assuming e is an enum represented by an int, I think the comparison "((long
long)e < 0" should not be always false. If e is an enum represented by an
unsigned, the warning would be valid, but "e < 0" should then also be always
false.
Compiling as plain C or adding a value larger than INT_MAX, enums seem to be
consistently unsigned. Adding a negative value, enums seem to be consistently
signed.
The same thing happens in all versions: 3.4.6 4.1.2 4.2.4 4.3.6 4.4.7 4.5.4
4.6.4 4.7.3
{{{
/* { dg-do run } */
/* { dg-options "-fno-strict-enums -Wtype-limits" } */
extern "C" void abort();
enum E {A, B};
long long f(int x) { return x; }
long long f(unsigned x) { return x; }
int main()
{
E e = (E)-1;
if (sizeof(e) >= sizeof(long long)) // First check that test makes sense.
return 0;
if (((long long)e < 0) != (e < 0)) /* { dg-bogus "comparison is always
false" } */
abort();
if (((long long)e < 0) != (f(e) < 0)) /* { dg-bogus "comparison is always
false" } */
abort();
}
}}}
More information about the Gcc-bugs
mailing list