GCC C bug: sizeof a union of structs returns zero value

2004-12-16 Thread Hugh Daniel
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

  Note, I gave up on GNATS after repeatedly getting this error message
no matter what I did to the text:

"""
You have not described how to repeat the bug
You have not defined a category for the bug
"""

  If there is a maintainer of the <[EMAIL PROTECTED]> bot I would
be happy to help debug the problem with your script.

||ugh


Submitter-Id:   net
Originator: Hugh Daniel
Organization:   Xelerance Corporation
Confidential:   no
Synopsis:   sizeof a union of structs returns 0, yeilding bogus behavior
Severity:   non-critical
Priority:   low
Category: c
Class:  sw-bug
Release:3.4.3
Environment:Linux, Solarus, MacOS X
System: Linux *.toad.com 2.6.9 #1 Thu Nov 11 23:34:13 PST 2004 i686 
i686 i386 BSD/GNU/Linux
Architecture:   i686
host:   i686-pc-linux-gnu
build:  i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc-3.4.3/configure
Description:
  Short version:  the sizeof a union of structs returns zero
in most recent GCC's.  Older GCC's return valid sizes.
 
  In porting some network code to SPARC I noticed an odd
warning message (warning: declaration does not declare
anything) which in the original context suggested something
was wrong.  After some investigation it turned out that an
array was being created but with zero size due to a sizeof
returning zero, though none of this was clear from the warning
message.

  The size of the array was set by a sizeof a union of two
structures (in_addr4 and in_addr6...).  In some gcc's a
reasonable value is returned and in others a very unreasonable
value of zero is returned.  A static array of size zero is
very likely to cause bad things to happen when assigned to...

  There is a 4 line C code example of the failure below.

  I have tested this on 5 hosts with 8 versions of GCC and
find a mixure of working and non working systems.  It seems
that around about 3.3 something changed in GCC such that
taking the sizeof a union of structs returns zero.  I would
have expected it to return the largest size of the unions
members (including any padding the architecture might
require).

  Note that telling folks to use a max function based on the
?: construct will start breaking down when there are three or
more items in the union, so while that will sove MY problem
today there still a bug in gcc.

  I suspect this could be a common problem as taking the
sizeof a union is not uncommon and resulting problems will be
of the memory corruption form, often quite hard to find.

  Please reference section 6.5.3.4, paragraph #3 of "August 3,
1998" (N843) ISO draft C standard to see why I believe this
is a bug.  I have found nothing in the NEWS, Changlogs
etc. that clearly states that there is a reason for the
current broken behavior.

  Fails on these gcc versions (host arch):
powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, 
Inc. build 4023)
gcc (GCC) 3.4.3 (sun4u)
gcc (GCC) 3.4.3 (i686)
gcc-3.4 (GCC) 3.4.2 (Debian 3.4.2-2) (SPARC)
gcc (GCC) 3.3.4 (Debian 1:3.3.4-13) (SPARC)
gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1666) (PPC)

  Works:
gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (i686)
gcc (GCC) 3.2.1 20030202 (Red Hat Linux 8.0 3.2.1-7) (i686)
gcc 2.96 (i686)

How-To-Repeat: gcc sizeof_fails.c
  Here is the simplest test case to show and repeat the bug:
"""
cat > sizeof_fails.c < sizeof_fails.c <
struct aaa { int aaa_int; };
struct bbb { char bbb_char; };
char ccc[ sizeof( union{ struct aaa; struct bbb; })];
int main(){
  printf("addr of ccc 0x%x\n", ccc);
  printf("size of ccc 0x%x\n", (unsigned int) sizeof(ccc));
  printf("unin of ccc 0x%x\n", (unsigned int) sizeof( union {struct aaa; struct 
bbb;}));
  printf("sily of ccc 0x%x\n", (unsigned int) sizeof( union silly {struct aaa; 
struct bbb;}));
}
EOF
gcc sizeof_fails.c
./a.out
"""
  Here are examples of the aboves output:
Works (i686):
"""
$ /usr/bin/gcc sizeof_fails.c
$ ./a.out
addr of ccc 0x8049584
size of ccc 0x4
unin of ccc 0x4
sily of ccc 0x4
$ /usr/bin/gcc --version
gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
"""

Fails (sun4u):
"""
$ gcc sizeof_fails.c
sizeof_fails.c:4: warning: declaration does not declare anything
sizeof_fails.c:4: warning: declaration does not declare anything
sizeof_fails.c: In function `main':
sizeof_fails.c:8: warning: declaration does

Re: GCC C bug: sizeof a union of structs returns zero value

2004-12-17 Thread Hugh Daniel
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

  My GCC sizeof a union of structs bug seems to be  pilot error after
all... 

  So Hugh Redelmeier found the actual bug when we were looking at the
various details of memory allocation: we were not declaring any struct
identifiers to take the size of.  This is the solution:

char ccc[ sizeof( union{ struct aaa; struct bbb; })];
char ccc[ sizeof( union{ struct aaa  ; struct bbb  ; })];
char ccc[ sizeof( union{ struct aaa Ignore_Me; struct bbb Ignore_Me_Too; })];
^ ^

  One might argue that Draft n2794.txt "6.7 Declarations" paragraphs
#2 and #6 are at odds in this case, one saying the lack of an
identifier is an error and the other saying it's optional.  I leave
this for you to decide.

  I will point out that the behavior of the C compiler has changed and
that this should be documented.

  Thanks for GCC folks.

||ugh Daniel

-BEGIN PGP SIGNATURE-
Comment: For the matching public key, finger the Reply-To: address.

iQCVAwUBQcLiZ1ZpdJR7FBQRAQKcmQQA67Lx2VmQ3/A6iBhTBVHFxPWQtzcNntg1
R8pZNawG1TmwbklELSl9WGWJP6v9wrUeqvdMzLTDhxQWFJACg972ExSFdUGmCg6+
nq21wDDFiMikTimYflM/XVSa0WV6ZXZHEHwP7gKe9bqOBmTsEuFWGmbsrj7H76X3
jjJHkpL9qpM=
=4XbY
-END PGP SIGNATURE-