[net.lang.c] Re^3: offsets in structures.

kendall@wjh12.UUCP (Sam Kendall) (10/21/84)

> > [An expression for finding the byte offset of an object:]
> >     (char *)(&((struct foo *)&end)->element) - (char *)&end
> 
> Good idea, except am not sure &end is the best symbol to use.  Is &end
> actually guaranteed to refer to a legal address by itself?  What about the
> other "&e" symbols:  etext and edata?  Is it legal is we replace "&end" with
> "(&end-sizeof (struct foo))"?
> -- 
> 	Geoff Kuenning

   You have a good point.  On a segmented architecture (8086 or Z8000),
I suppose &end may point to a location which is less than sizeof (struct
foo) bytes away from the end of a segment--either end.  So neither
"&end" nor "(&end-sizeof (struct foo))" (actually, it would have to be
"((char *)&end - sizeof (struct foo))") is guaranteed to work, because
either may cause the above expression to overflow a segment boundry.  So
the only solution is to use the address of an actual structure object.

   I am really thinking too low-level, I guess.  If &end doesn't point
to allocated storage, I should assume that pointer arithmetic on it is
nonportable, on principle.  However, it seems to me that UNIX tells you
that &end points to a sort of variable-length "object", "the heap".
This "object" starts out at zero bytes long, and "sbrk" and "brk" can be
used to make it bigger.  It is interesting that on segmented
architectures, pointer relational comparison may not work between the
ends of this "object".

	Sam Kendall	  {allegra,ihnp4,ima,amd}!wjh12!kendall
	Delft Consulting Corp.	    decvax!genrad!wjh12!kendall

mjs@rabbit.UUCP (M. J. Shannon, Jr.) (10/21/84)

How about this fragment for a `portable' method of computing structure
offsets:

	f(sp)
	struct stuff *sp;
	{
		int	offset; /* may need to be long for some */

		offset = (char *) &sp->member - (char *) sp;
	}

If a (valid) pointer to the structure in question is not available,
it is easy (if costly on some machines) to make an auto:

	f()
	{
		struct stuff local_stuff;
		int	offset;	/* may need to be long... */

		offset = (char *) &local_stuff.member - (char *) &local_stuff;
	}

To my knowledge, this is the `ultimate' in portable offset calculation.
I would be extremely interested in hearing about any machines on which
either fragment fails to store the correct offset in `offset'.

	Yours in portability (just west of Outer Slobovia),
-- 
	Marty Shannon
UUCP:	{alice,rabbit,research}!mjs
	(rabbit is soon to die.  Does this mean alice is pregnant?  Yup!)
Phone:	201-582-3199

duk@klipper.UUCP (Duk Bekema) (10/25/84)

In article <3252@rabbit.UUCP> mjs@rabbit.UUCP (M. J. Shannon, Jr.) writes:
>How about this fragment for a `portable' method of computing structure
>offsets:
>
>	f(sp)
>	struct stuff *sp;
>	{
>		int	offset; /* may need to be long for some */
>
>		offset = (char *) &sp->member - (char *) sp;
>	}

Wouldn't you want to return it? :-)

				Duk Bekema
				...!{seismo|decvax|philabs}!mcvax!vu44!duk