Maybe he forgot the delicate details? The issue may happen if this example was incomplete (my "completion" may need some tweaking to make it more realistic):

#define make_a_bar(ppInstance) *(unsigned**)(&ppInstance)=make_a_uint(sizeof(struct bar))
   make_a_bar(foo->bar);
   foo->bar->none = value;

Then, the author of make_a_bar() is getting what he deserved.

I am not sure if the following would break as well:

   #define make_a_bar()   (struct bar*)make_a_uint(sizeof(struct bar))
   foo->bar=make_a_bar();
   foo->bar->none = value;

Since gcc should know that foo->bar of type "struct bar" has been updated before "value" gets written to "none" which is a field on object of type "struct bar".

Of course it wouldn't break.

But the reason I say that this is what you deserved, is that the cast is completely unnecessary. You should write this:

#define make_a_bar (ppInstance) \
 ((ppInstance)=(void *)make_a_uint(sizeof(struct bar)))

that is, you put the cast on the other side and don't play with the types of the lvalues. This is what happens all the time with malloc.

Paolo

Reply via email to