Is this a bug in some C compilers?

Suhas Joshi suhas at nlgvax.UUCP
Fri Jul 21 01:45:11 AEST 1989


>Am I correct to say that the program is not correct C, and that all compilers
>which compile it are wrong?

The usage a.b when a is not a structure is allowed. But it is not portable. 
This is allowed so that strict typing is not enforced. So, as long as
compilers issue a warning, it is acceptable. It is definitely not a bug.
As long as a in a.b is lvalue, it is assumed to be a structure, if it is not.
See K&R C book's C reference manual sections 7.1 and 14.1 for details.

But my decision to post this was for other reason than pointing out this.
The reason is how implicit assumption that fix0 and fix1 are allocated around
t is wrong, and makes programs which rely on such assumption non-portable.
The assumption is implicit due to the use of the following printf about
addresses of fix0, fix1 and t.

[ Stuff deleted ]
>int fix0;
>struct link * t;
>int fix1;
>
>main ()
>{
>	printf ("t lies at %1d, brk is at %1d\n", (int)(&t), (int)sbrk(0));
>	printf ("Addresses of %1d byte objects around t : %1d and %1d\n",
>		sizeof(int), (int)(&fix0), (int)(&fix1));

[stuff deleted]

See the following output generated by SUN 3 running SunOS 4.0, and note that
out of 12 bytes allocated for fix0, fix1 and t. t has last 4, fix0 has first 
4, and fix1 has middle 4. So, fix0 and fix1 are not around t in addresses but
before t.

t lies at 131400, brk is at 131408
Addresses of 4 byte objects around t : 131392 and 131396
Assignment worked.
Value 5 has been put at address 131404

This happens because compile generates following assembly directives in the
same order as the definitions of the variables in the source
LL0:
	.data
	.comm	_fix0,4
	.comm	_t,4
	.comm	_fix1,4
	.text
	.proc
[Assembly code deleted]

But .comm tells assembler not to allocate storage but to leave it to linker.
So, linker reserves 12 bytes, and later allocates 4 each to t, fix1 and fix0
in that order, from the last address in the 12 byte area. So, the allocation
depends on how linker looks at the 12 bytes (low to high or high to low), and
on the order in which t fix1 and fix0 are referenced., because that is the
order in which linker has allocated. First printf refers to t, next refers
to fix0 and fix1, but the order of references is fix1 and fix0 because of
the order of parameter pushing on the stack.

So, beware of dependencies on order of definition of data and assumptions
about their allocation in the same order.

Suhas M. Joshi.					E-Mail: suhas at pcg.philips.nl
Philips Research Labs.,				Tel: +31 40 892336
Project Centre Geldrop, Building XP
Willem Alexanderlaan 7B, 5664 AN Geldrop	The Netherlands
-- 
Suhas M. Joshi.					E-Mail: suhas at pcg.philips.nl
Philips Research Labs.,				Tel: +31 40 892336
Project Centre Geldrop, Building XP
Willem Alexanderlaan 7B, 5664 AN Geldrop       The Netherlands



More information about the Comp.lang.c mailing list