I think you’re right, it’s not possible to implement memmove
efficiently in standard C.
The only truly portable way to test whether the regions overlap, I think, is something like this:
for (size_t l = 0; l < len; ++l) {
if (src + l == dst) || (src + l == dst + len - 1) {
// they overlap, so now we can use comparison,
// and copy forwards or backwards as appropriate.
...
return dst;
}
}
// No overlap, doesn't matter which direction we copy
return memcpy(dst, src, len);
You can’t implement either memcpy
or memmove
all that efficiently in portable code, because the platform-specific implementation is likely to kick your butt whatever you do. But a portable memcpy
at least looks plausible.
C++ introduced a pointer specialization of std::less
, which is defined to work for any two pointers of the same type. It might in theory be slower than <
, but obviously on a non-segmented architecture it isn’t.
C has no such thing, so in a sense, the C++ standard agrees with you that C doesn’t have enough defined behaviour. But then, C++ needs it for std::map
and so on. It’s much more likely that you’d want to implement std::map
(or something like it) without knowledge of the implementation than that you’d want to implement memmove
(or something like it) without knowledge of the implementation.