[Bug c/30260] New: Enumeration types and enumeration constants erroneously given unsigned types
rda at lemma-one dot com
gcc-bugzilla@gcc.gnu.org
Tue Dec 19 20:51:00 GMT 2006
The comments at the top of the following source file describes the bug.
This happens on gcc 4.1.0 too. for what it is worth, uname -a and
gcc -v output for the Linux box I am currently using are at the end.
The actual code is only 14 lines and only includes stdio.h.
/* source file: enum_bug.c
*
* An anomaly in gcc C: according to C99 6.7.2.2, enumeration constants
* must have signed int type and, if some enumeration constant has
* a negative value, then the integer type compatible with the
* enumeration type must be a signed type. It seems to be possible
* to fool gcc into misapplying these rules by making the type of
* the integer constant expression giving the value of an enumeration
* constant an unsigned integer type. This was first observed in a case
* where the expression involved sizeof, but just a cast to unsigned or using
* an unsigned integer constant has the same effect as seen below:
*
* This has been observed on various Linux PCs and on Mac OS X with
* several versions of gcc (3.4.1 up to 4.1.0).
*
* Compiling and running with
*
gcc -o enum_bug enum_bug.c ; ./enum_bug
*
* produces no diagnostics and code that prints out the following:
*
(a < 0) = 1, (A2 < 0) = 1, A{1,2} = +0, -1
(b < 0) = 0, (B2 < 0) = 0, B{1,2} = +0, -1
*
* Compiling and running with:
*
gcc -ansi -pedantic -o enum_bug enum_bug.c; ./enum_bug
*
* results in an an incorrect warning
*
enum_bug.c:38: warning: ISO C restricts enumerator values to range of `int'
*
* but with code that correctly prints out:
*
(a < 0) = 1, (A2 < 0) = 1, A{1,2} = +0, -1
(b < 0) = 1, (B2 < 0) = 1, B{1,2} = +0, -1
*
* Rob Arthan (rda at lemma-one dot com) 19th December 2006
*/
#include <stdio.h>
enum A {A1 = 0, A2 = A1 - 1};
enum B {B1 = 0u, B2 = B1 - 1};
int main(void)
{
enum A a = -1;
enum B b = -1;
printf("(a < 0) = %d, (A2 < 0) = %d, A{1,2} = %+d, %+d\n",
(int)(a < 0), (int)(A2 < 0), (int)A1, (int)A2);
printf("(b < 0) = %d, (B2 < 0) = %d, B{1,2} = %+d, %+d\n",
(int)(b < 0), (int)(B2 < 0), (int)B1, (int)B2);
return 0;
}
/*
* uname -a:
Linux localhost 2.6.8.1-12mdk #1 Fri Oct 1 12:53:41 CEST 2004 i686 Pentium III
(Coppermine) unknown GNU/Linux
* gcc -v:
Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/specs
Configured with: ../configure --prefix=/usr --libdir=/usr/lib
--with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info
--enable-shared --enable-threads=posix --disable-checking --enable-long-long
--enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions
--enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu
--with-system-zlib
Thread model: posix
gcc version 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)
*/
--
Summary: Enumeration types and enumeration constants erroneously
given unsigned types
Product: gcc
Version: 3.4.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rda at lemma-one dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30260
More information about the Gcc-bugs
mailing list