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