Useful macro...or dangerous??

ark at alice.UUCP ark at alice.UUCP
Fri Apr 29 08:48:08 AEST 1988


In article <221 at raunvis.UUCP>, kjartan at 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.



More information about the Comp.lang.c mailing list