cperformancepointersc-stringsmemmove

Does comparing two pointers do more than to just check their adresses?


I'm rewriting part of libc, more specifically memmove as an exercise and after being unable to do it myself I looked for its source code and found this (and variations of it):

void    *memmove(void *dest, const void *src, size_t n)
{
  char *d = dest;
  const char *s = src;
  if (d < s)
    while (n--)
      *d++ = *s++;
  else
    {
      char *lasts = s + (n-1);
      char *lastd = d + (n-1);
      while (n--)
        *lastd-- = *lasts--;
    }
  return (dest);
}

My question concerns the 5th line if (d < s) for me this would only make sense if d and s contained the size of both dest and src which as far as my understanding goes is not true. So is this comparison doing anything besides checking the position of the addresses or is my understanding of pointers completely flawed?

Is there any purpose to this code? Sorry in advance if I am completly wrong pointers can be very confusing.


Solution

  • is this comparison doing anything besides checking the position of the addresses?

    No. It checks if d has a lower address than s. If it does, it selects the first strategy, to copy from the beginning of the memory area and forward - otherwise it copies from the end of the memory area backwards

    This is to not mess up the result in case [d,d+n) and [s,s+n) are overlapping.

    Example:

         +---+---+---+
    src  | x | y | z |
         +---+---+---+---+
    dest     |   |   |   |
             +---+---+---+
         ^               ^
         |               |
    low mem addr    high mem addr
    

    Here the second strategy must be chosen. Consider what would happen if the the first strategy is chosen instead:

    dest[0] = src[0]; // which is x
    dest[1] = src[1]; // which is ... x, because the above op overwrote the y