Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-crg!rutgers!dayton!viper!dave From: dave@viper.UUCP (David Messer) Newsgroups: comp.lang.c Subject: Re: structure element offsets Message-ID: <419@viper.UUCP> Date: Fri, 5-Dec-86 03:50:46 EST Article-I.D.: viper.419 Posted: Fri Dec 5 03:50:46 1986 Date-Received: Thu, 4-Dec-86 06:41:05 EST References: <1096@spice.cs.cmu.edu> <768@nike.UUCP> <3622@watmath.UUCP> <386@viper.UUCP> <3695@watmath.UUCP> Reply-To: dave@viper.UUCP (David Messer) Organization: Lynx Data Systems, Minneapolis, MN Lines: 53 Keywords: structure, offset In article <3695@watmath.UUCP> rbutterworth@watmath.UUCP (Ray Butterworth) writes: >In article <386@viper.UUCP>, dave@viper.UUCP (David Messer) writes: >> A simpiler definition of the OFFSET macro is the following: >> #define OFFSET(mos) ((long)(&(((char *)0)->mos))) >> This will produce a proper offset on almost all machines. (But >> not all, some machines have different formats to pointers to >> different types. Also, this macro assumes that (long)((char *)0) == 0L.) > >"on almost all machines" means it is totally wrong on some machines. >What is the point of making something simpler if it's going to be >wrong? >How about "#define OFFSET(mos) 4"? That's really simple and will >also be correct sometimes. >What is the point of bothering to assume that (long)(char*)0 is 0? >Why not simply subtract whatever (char*)0 really is from the other >pointer and always get the correct answer on all machines (as I >originally suggested)? > >On any one machine, the simplest and most complicated forms of this >macro will generate exactly the same code (assuming both are correct). >What is it you think you are gaining by "simplifying" it? > Because your solution doesn't work all the time either. There are some machines in which pointers to different types are unrelated in format. In other words a cast such as (type1 *)(type2 *)x will not always give a meaningful answer. According to K&R all that is required is that (type *)(long *)x == x. Since one cannot make a macro that will work on a arbitrary machine, other considerations apply when writing code such as this. For instance you assume that (x - (char *)0) will compile to the same code as (x). I have known some brain-damaged compilers to actually generate code for the cast and the subtract. There are no machines to my knowledge where (long)(char *)0 != 0L and other problems (such as casting of pointers) don't prevent the offset macro to work. > >Besides, what makes you think you can get away with ((char*)0)->mos? >Compilers which accept this (e.g. BSD) give this warning: >"xxx.c", line 15: warning: struct/union or struct/union pointer required >And if two structures should happen to have members with the same name: >"xxx.c", line 15: nonunique name demands struct/union or struct/union pointer I will conceed that you have a point here, however, for good or ill, C has been defined such that all members-of-structures share the same name-space. If you have a compiler which gives you these helpful hints, it is an easy matter to add a structure name parameter to the macro. -- Disclaimer: | David Messer I'm always right and I never lie. | Software Consultant My company knows this and agrees | UUCP: ihnp4!quest!viper!dave with everything I say. | ihnp4!meccts!viper!dave