3 ms·
You've phrased the result of the UB in a way that disguises the benefit: your complaint is adding a special case, and for an arbitrary memcpy(x, y, n) call, the
by dbaupp 9y ago
You've phrased the result of the UB in a way that disguises the benefit: your complaint is adding a special case, and for an arbitrary memcpy(x, y, n) call, the compiler would have to provide it isn't in this special case (i.e. n != 0) or else it couldn't assume x != nullptr && y != nullptr. The codegen benefit isn't when n == 0, but when n is unknown.
- quotemstr 9y agoHuh? What special case? When n is zero, we copy no bytes. That's the opposite of a special case: it's a general rule!
- noselasd 9y agoThis is not how an assembly programmer sees this problem. (memcpy is often hand coded in assembly). This means the code takes advantage of CPU pipelines and branch predictions, which means the source/destination pointer might be de-referenced and loaded into a register before the number of bytes is being inspected, or the assembly is executed with a 0 value, which still makes the CPU do a load or store on the src or dest pointer. This is being done to gain performance, and doing things in another order or explicitly validating the input decreases performance. If then the src/dest pointer is NULL, the above scenario plays out badly, but in order to not sacrifice performance, the burden is placed on the caller to correctly use memcpy() instead of memcpy() detecting invalid use.
- quotemstr 9y agoFor memcpy(x,y,n), x and y can refer to the last byte on a page. What are you going to do, prefetch that one byte?
- dbaupp 9y agoThe rule is memcpy(x, y, n) is undefined if x or y are null. Making it defined if n is zero is a special case inside that rule.
- quotemstr 9y agoSure: except that rule isn't useful. You can't _rely_ on undefined behavior, so preserving the rule that "memcpy(x, y, n) is undefined if x or y are null" isn't helpful. OTOH, preserving the rule that memcpy(x,y,n) is defined for all x,y when n==0 really is useful.
- dbaupp 9y agoIt is useful. I'm focusing on the effect on code generation: the compiler relies on that rule to deduce that x and y are not null. The special case for n==0 makes it harder for the compiler to deduce the non-null-ness and thus harder for it to optimise based on that. Restricting when optimisations can be applied is the effect of your special case. You might not agree with this as a design decision but I'm not arguing that this is the right trade-off, just answering: > I don't think your optimization actually exists. In what possible world can we generate better code by assuming that for memcpy(x,y,n), when n==0, x!=nullptr||y!=nullptr?