Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site watmath.UUCP
Path: utzoo!watmath!kpmartin
From: kpmartin@watmath.UUCP (Kevin Martin)
Newsgroups: net.lang.c
Subject: Re: offsets in structures.
Message-ID: <9386@watmath.UUCP>
Date: Fri, 12-Oct-84 14:11:54 EDT
Article-I.D.: watmath.9386
Posted: Fri Oct 12 14:11:54 1984
Date-Received: Sat, 13-Oct-84 06:51:28 EDT
References: <393@orion.UUCP> <6080@mcvax.UUCP>
Reply-To: kpmartin@watmath.UUCP (Kevin Martin)
Organization: U of Waterloo, Ontario
Lines: 30

>Watch out!  I did a similar thing to calculate the width of a structure:
>
>	(int) ((struct foo *)0 + 1)
>
>This would give me the sizeof a struct foo, ROUNDED UP to the necessary
>alignment.
>	Guido van Rossum
>	guido@mcvax.UUCP


First off, if your 'sizeof' operator doesn't give you the size already rounded
up to a multiple of the required alignment, you're in trouble!

Second, on some hardware, casting a pointer to an integeral type *DOESN'T
GIVE A BYTE INDEX FROM BYTE ZERO*! On a Honeywell Level 66 (or a 6000
or a DPS8 or a DPS88...), the above expression would give the value
01000000 (if sizeof(struct foo) == sizeof(int) which is 4 bytes).

A better expression, which is a bit closer to legit (but still
subject to compiler bugs) is:
    (char *)((struct foo *)0 + 1) - (char *)0
Or, for getting the offset of a struct element,
    (char *)(&((struct foo *)0)->element) - (char *)0

The two reasons that these still aren't legit are:
(1) They should really use NULL, rather than 0 (but this is just being picky)
(2) It is not at all clear that any operation on a NULL pointer other than
    comparison and asignment is allowed. The above code does a pointer+int,
    then a pointer difference, both using NULL pointers.
                     Kevin Martin, UofW Software Development Group