Paolo Bonzini wrote:

foo->bar = make_a_bar();
foo->bar->none = value;

being rendered as:

call make_a_bar
foo->bar->none = value
foo->bar = <result of make_a_bar()>

You are not describing a C compiler.

Um, I'm describing what gcc did?

I think he meant

x = make_a_bar ();
x->none = value;
foo->bar = x;

I don't know if this is a valid optimization, but I wouldn't be surprised if it is.

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;


In this case strict-aliasing starts its act. The store to foo->bar is done through a different type (pointer to unsigned), which tells gcc that foo->bar->none accesses one object (type bar), while the construction of foo->bar accesses a different object type (unsigned int). In this case this code is undefined and the compiler can reorder these two lines.

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".


 Michael

Reply via email to