Subject: Re: CVS commit: basesrc/usr.bin/file
To: None <tech-userlevel@netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 06/06/2002 13:54:31
[ On Thursday, June 6, 2002 at 12:11:55 (+0100), David Laight wrote: ]
> Subject: Re: CVS commit: basesrc/usr.bin/file
>
> Except that it is very useful to be able to use structures to
> map over device register sets.

If you believe that's possible then you are not using the C Language but
rather some bastardised creation of your own mind.  It might be "useful"
to you, but it's just flat out wrong for portable code, especially of
course if you're using bitfields, but even without the layout of
structures is highly implementation dependent.  Harbison and Steele[*]
say:

	Depending on packing strategies is dangerous for several
	reasons.  First, computers differ on the alighment constraints
	on data types.  [[...]]

	Second, the restrictions on bit-field widths will be different.
 	[[....]]

	Third, computers differ in the way fields are packed into a word
	-- that is, in their "byte ordering.".  [[....]]

> 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.

Harbison & Steele suggest just:

	#define offsetof(type,memb) ((size_t)&((type *)0)->memb)

and I've used that successfully in some widely portable code.....

They do go on to warn that an implementation need not permit such use of
the null pointer constant in that fashion, but I've never encountered a
compiler implementation that disallowed it.....


> On Wed, Jun 05, 2002 at 01:36:56PM -0400, der Mouse wrote:
> > 
> > someone wrote:
> > >
> > > 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

Harbison & Steele interpret "sequentially allocated" to mean:  (p. 135)

	C compilers are constrained to assigne components increasing
	memory addresses in a strict order, with the first component
	starting at the beginning address of the structure itself.

	Given two pointers 'p' and 'q' to components within the same
	structure, (p < q) will be true if and only if the declaration
	of the component to which 'p' points appears earlier within the
	structure declaration than the declaration of the component to
	which 'q' points.


[*] "C: A Reference Manual", Samuel P. Harbison and Guy L. Steele, Jr.,
    Fourth Edition, Prentice Hall, 1995.  (There is now a Feb. 2002 Edition)

-- 
								Greg A. Woods

+1 416 218-0098;  <gwoods@acm.org>;  <g.a.woods@ieee.org>;  <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>