Subject: Re: CVS commit: basesrc/usr.bin/file
To: <>
From: David Laight <david@l8s.co.uk>
List: tech-userlevel
Date: 06/06/2002 12:11:55
On Wed, Jun 05, 2002 at 01:36:56PM -0400, der Mouse wrote:
> > Reordering members of a structure is a violation of the C standard
> 
> So is int smaller than 8 bits, yet I've seen programs touted as C
> compilers that by default do 8-bit ints.  (Targeted at embedded
> processors, to be sure; the 8051 is the one I remember.)  Strictly
> speaking, such things are not actually C compilers, being instead
> almost-but-not-quite-C compilers.

Or maybe C-like-syntax-compilers, or 'how to make your embeddeb
program not fit in the space available' compilers.
If you've only got 4k instructions writing in the native assembler
won't do any harm.  You'll probably end up writing chunks of it
that way later for speed/size reasons anyway.

> I've never understood why compilers are prohibited from rearranging
> struct members.  As long as it's done deterministically, so as to not
> break separate compilation, I can't see any harm in it.

Except that it is very useful to be able to use structures to
map over device register sets.

Mind you a warning about 'excessive' padding wouldn't go amiss.

I suppose it wouldn't do much harm to 'put fields in the first
space in which they fit, given their alignment requirements'.
Anyone who cares about ordering probably hasn't left any
gaps.  Wholesale re-ordering (eg into alphabetic or hash value
order) wouldn't really be useful.

> (You would
> have to either require that the first member be nailed down, or give up
> the guarantee about converting between pointers to structs and pointers
> to their first members; I'd prefer the latter.)

Certainly the 'inverse' of offsetof() that given a structure type,
member name, and pointer (assumed to the member) returns the address
of the structure.  Something like (untested):

#define structof( type, member, ptr ) ((type_t *)((char *)(ptr) - \
					offsetof( type, member )))
Although maybe including ((ptr) - ((type *)0)->member) in the sum
somewhere might be handy...

FWIW netbsd seems to define offsetof as:
    ((size_t)(unsigned long)(&((type *)0)->member))
the double cast is pointless so why not:
    ((size_t)(&((type *)0)->member))
or even:
    (((char *)&((type *)0)->member) - (char *)0)
which is always the type that size_t should be.

> 
> > section 6.2.5.20 of C99 requires that members of a structure be
> > sequentially allocated
> 
> Of course, what does "sequentially allocated" really mean?  I'm
> wondering if this can be fudged by the "as if" rule.

Doubtful, the user can check because offsetof() gives the
distance from the start of the structure - and needs to be
monatonically increasing.  Also
	*(member_type *)((char *)ptr + offsetof( type, member ))
has to return the same data as ptr->member

	David

-- 
David Laight: david@l8s.co.uk