This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


-----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 <gcc-gnats@gcc.gnu.org> 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 <<EOF
struct aaa { int aaa_int; };
struct bbb { char bbb_char; };
char ccc[ sizeof( union{ struct aaa; struct bbb; })];
int main(){ return 0; }
EOF
gcc sizeof_fails.c
./a.out
"""

	  Here is a slightly more verbose test case:
"""
cat > sizeof_fails.c <<EOF
#include <stdio.h>
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 not declare anything
sizeof_fails.c:8: warning: declaration does not declare anything
sizeof_fails.c:9: warning: declaration does not declare anything
sizeof_fails.c:9: warning: declaration does not declare anything
$ ./a.out
addr of ccc 0x209a8
size of ccc 0x0
unin of ccc 0x0
sily of ccc 0x0
$ gcc --version
gcc (GCC) 3.4.3
"""

Fix:
	Unknown to me.
	At least re-write the error message so that we know what
	construct on that line is not declaring 'anything'.  I had
	to guess and explore to figure out what was wrong.
	
-----BEGIN PGP SIGNATURE-----
Comment: For the matching public key, finger the Reply-To: address.

iQEVAwUBQcJJ6Qair3ZYNYS4AQJsyAgAyseDerUfxEeklqHG2SY+ncxNLOclS7Uz
knGeLlgTuMMe92ZQCl6zdsSKxmTqW+n4GeyWhVgMG1g//S+RONwTW0RWeUZXJBTv
LBc6DT9oWfi/rYj+KLP+1bYCDP1IMMHMjuYw82t/udFjpKJY7nfqUYq9nhjAjZ9g
eg+Uq/ZY2FbiPYMVBIN1ks0xlfoASIC0CUnPfgzsJ+A21qLWEX98jxVnEvjJKvVj
DKKsBo3nZWlQqpItJtK4SuJC3SDAqqvZV1L1BPUDhfi4nVtbnuJPC4F3rfbhTznU
WYQ3D58pKTyNcfoTJRjcA5PkQbkiDfeZGcNTzr79sglD5cKaEUzZDg==
=aovX
-----END PGP SIGNATURE-----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]