3 ms·
Ouch. Didn't think about that compilers can then assume passed pointers aren't NULL. And proceed to optimize your NULL checks away, because that memcpy would ha
by vardump 10y ago
Ouch. Didn't think about that compilers can then assume passed pointers aren't NULL. And proceed to optimize your NULL checks away, because that memcpy would have been undefined behavior.
It seems so obvious after reading that. Should always ask oneself "what can the compiler prove as a consequence of this undefined behavior?".
So, you're right, memcpy(NULL, NULL, 0) should be defined as a no-op.
- quotemstr 10y agoSome of us been trying to highlight for a long time now how compilers are taking unjustifiable liberties with undefined behavior
- vardump 10y agoWell, undefined behavior is generally a good thing. It enables a lot of very reasonable optimizations. Zero-length memcpy pathway to UB is not obvious, because whether the whole thing is UB depends on whether compiler can statically prove the length to be zero. Ugh.
- quotemstr 10y agoI think the statically-prove-length-is-zero thing is a distraction. What do you think of memcpy(ptr1, ptr2, 1)? The compiler should be able to assume (legitimately, this time) that ptr1 and ptr2 are non-null. The problem isn't a special case for zero length: the problem is the lack of a special case for zero length.
- scott_s 10y agoUndefined behavior does not enable optimizations. Rather, the compiler may conclude that something must be true, because the alternative would be undefined behavior. Then, it may make optimization decisions based on that thing being true, causing potentially mysterious errors if, in fact, that thing is not true because the programmer made a mistake. It's also possible you're confusing undefined behavior with implementation defined behavior.