This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/30260] New: Enumeration types and enumeration constants erroneously given unsigned types
- From: "rda at lemma-one dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 Dec 2006 20:51:38 -0000
- Subject: [Bug c/30260] New: Enumeration types and enumeration constants erroneously given unsigned types
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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