<div dir="ltr"><div>The rationale given does not seem to square (IMHO) with the ubiquitous practice of having 0- or 1-length array at the end of a struct and then allocating additional elements for it using malloc, or the so-called "struct hack":</div><div><br></div><div> <a href="http://c-faq.com/struct/structhack.html">http://c-faq.com/struct/structhack.html</a></div><div><br></div><div>For example:</div><div><br></div><div> typedef struct {</div><div> enum inst_type type;</div><div> unsigned num_ops;</div><div> struct operand ops[1];</div><div> } inst;</div><div><br></div><div> // allocate an instruction with specified number of operands</div><div> int *allocate_inst(unsigned num_operands) {</div><div> char *mem = malloc(sizeof(inst) + sizeof(struct operand) * (num_operands-1));</div><div> return (inst *) mem;</div><div> }</div><div><br></div><div>Or maybe the reasoning is that computing a pointer off the beginning of something (e.g. &c - X) is somehow worse than computing a pointer off the end of something (e.g. &c + X)?</div><div><br></div><div>Than</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 22, 2016 at 11:41 AM, Chuang-Yu Cheng via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reply from Michael:<br>
<br>
&x points to the start of object x, and &x - something (something != 0)<br>
points outside object x. 'c' was a complete object, so &c-8 points<br>
outside any object, hence the formation of that pointer is already<br>
invalid (as is its dereference).<br>
<br>
<a href="https://gcc.gnu.org/ml/gcc/2016-03/msg00185.html" rel="noreferrer" target="_blank">https://gcc.gnu.org/ml/gcc/2016-03/msg00185.html</a><br>
<span class="im HOEnZb"><br>
>>On Fri, Mar 18, 2016 at 8:46 AM, Daniel Berlin <<a href="mailto:dberlin@dberlin.org">dberlin@dberlin.org</a>> wrote:<br>
>><br>
>> I *think the argument* goes that this is a 20 or 24 byte object, so if you *could* put something of type PB at c-8, you'd illegally overlap with the object at c.<br>
>><br>
>> Thus, there can't be an object of type PB at c-8.<br>
>><br>
>> (IE any valid object must be sizeof(PB) away in either direction, which means it's not possible for c->f1_ to clobber c no matter what bar does)<br>
<br>
</span><div class="HOEnZb"><div class="h5">>>> We discussed this issue briefly on the #gcc IRC channel.<br>
>>> Richard Biener pointed out that bar cannot make c point to &c - 8,<br>
>>> because computing that pointer would be invalid. So c->f1_ cannot<br>
>>> clobber c itself.<br>
>>><br>
>>> --<br>
>>> Markus<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</div></div></blockquote></div><br></div>