In addition to @Mark Bluemel good answer:
A difference between
memmove() is the ability to handle overlapping buffers. Notice the keyword
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
restrict roughly implies access to the buffer is not interfered with by other activity.
memCopy() code does not copy well overlapping buffers when the
source precedes the
destination. It is more like
void* memCopy(void* restrict destination, const void* restrict source, size_t size)
restrict, the compiler can invoke additional optimizations.
A solution to act like
memmove() involves looping up or down depending on which is greater
destination. The trick is that this compare for pointer greatness is not certainly possible in C.
memmove(), as a library function, has access to information C does not. Yet a compare of pointers converted to an integer is usually sufficient.
double is not the way to go.
*b = *a; is not guaranteed to copy the bit pattern nor potentially triggering a signaling not-a-number exception. Best to avoid involving floating-point concerns. Instead use a wide unsigned integer type, perhaps
unsigned long long, or
uint64_t. (Pros and cons for each. I'd go for
uint64_t when available.)
On ancient machines,
*b2 = *a2; can invoke a trap. Instead use
unsigned char *a2; unsigned char *b2;
memCopy(..., ..., 0) is properly handled. Bravo! - a common mistake avoided here.