Path: utzoo!mnetor!uunet!husc6!uwvax!dogie!uwmcsd1!tut.cis.ohio-state.edu!mailrus!umix!umich!mibte!gamma!ulysses!andante!alice!ark From: ark@alice.UUCP Newsgroups: comp.lang.c Subject: Re: Useful macro...or dangerous?? Message-ID: <7840@alice.UUCP> Date: 28 Apr 88 22:48:08 GMT References: <221@raunvis.UUCP> Organization: AT&T Bell Laboratories, Liberty Corner NJ Lines: 54 Keywords: macro In article <221@raunvis.UUCP>, kjartan@raunvis.UUCP writes: > #define EQ(A,B) equal(A,B,sizeof(*(A))) The function called by this macro does a byte comparison. Here's the trouble. The assertions in comments are not true on all machines, but are on some and that's what matters: struct bar { short a; /* two bytes of invisible padding here */ long b; }; struct foo { char c[sizeof(struct bar)]; }; /* now here's some code */ foo *fp1, *fp2; bar *bp1, *bp2; int i; fp1 = (foo *) malloc (sizeof (foo)); for (i = 0; i < 8; i++) fp1->c[i] = '?'; free ((char *) fp1); bp1 = (bar *) malloc (sizeof (bar)); fp2 = (foo *) malloc (sizeof (foo)); for (i = 0; i < 8; i++) fp2->c[i] = '!'; free ((char *) fp2); bp2 = (bar *) malloc (sizeof (bar)); This code is all clean and portable. Here's what's happening. If you free memory and then allocate the same amount again immediately, malloc will probably be nice enough to give you back the memory you just freed. Thus the assignments to c[i] initialize memory to a particular value, give it back to the system, and maybe get it back again. In any event, the memory addressed by bp1 and bp2 has probably been set to different values. Now some assignments: bp1->a = 3; bp2->a = 3; bp1->b = 7; bp2->b = 7; By any sensible definition of equality, bp1 and bp2 point to equal objects. Yet, because the invisible padding in these objects has been initialized to different values, the EQUAL macro above will show them as different.