Path: utzoo!mnetor!uunet!husc6!purdue!umd5!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Useful macro...or dangerous?? Message-ID: <11255@mimsy.UUCP> Date: 28 Apr 88 07:59:20 GMT References: <221@raunvis.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 56 Keywords: macro [Dangerous] In article <221@raunvis.UUCP> kjartan@raunvis.UUCP (Kjartan Pier Emilsson Jardedlisfraedi) writes: >... test the equality of two structures [of the same type]. >... I decided to build some sort of equality macro, and came down >on the following solution which seems to work. [Aside: the usual idiom is `came up with', giving perhaps the rather bizarre image of someone diving into a lake and emerging with a trout between his teeth :-) ] >(Of course if some members of a structure are pointers, then the >equal() function returns 0 if the pointers do not point to the same >adress). Now I would very much like to know whether this is a >foolproof way to test equality of structures, or is there a hidden >nasty little fellow who eludes me. There is: >#define EQ(A,B) equal(A,B,sizeof(*(A))) >[e.g., struct thing x, y; ... EQ(&x, &y)] Then `equal' is defined more or less to do what `memcmp' does. Aside from coding errors in equal (the one provided would not compile), there is a more insidious problem. Structures may contain `holes'; the holes are not necessarily set to any particular value, so two otherwise equal structures may compare differently. For instance, if I write struct holey { char ch; int i; } smokes, batman; there is often a `gap' between `ch' and `i'. The 4BSD Vax compiler, for instance, puts `i' at offset 4, leaving three bytes of hole before it. If these are automatic variables, setting smokes.ch and smokes.i leaves its hole untouched and full of random stuff left over from whatever was on the stack before. You *can* get around this, at some expense, by calling bzero() or memset() to set all structures, including the holes, to all-zero-bytes, but there is no guarantee that the compiler must never write onto the hole area. One could imagine an architecture in which byte stores are impossible, where writing to a single byte requires a `load, mask, or, store' sequence; in this case the compiler might elect to put a hole before or after every character in a structure, and just store a word each time, overwriting the previous hole contents. In short, it is safest not to do this. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris