Jump to: navigation, search

Prototype

Declared in string.h

void *memmove(void *dest, const void *src, size_t n);

Description

The memmove() function shall copy the first n bytes pointed to by src to the buffer pointed to by dest. Source and destination may overlap.

Return value

The memmove() function shall return the pointer dest; the function has no failure mode and no error return.

Implementation

In standard C, this can be implemented as:

#include <stddef.h> /* for size_t */
void *memmove(void *dest, const void *src, size_t n)
{
    unsigned char *pd = dest;
    const unsigned char *ps = src;
    if (__np_anyptrlt(ps, pd))
        for (pd += n, ps += n; n--;)
            *--pd = *--ps;
    else
        while(n--)
            *pd++ = *ps++;
    return dest;
}

Incomplete unit, portable C90 in implementation namespace; public domain; past reviewers: none; current reviews: none

Non-portable components

A macro or function such that, for any two pointers p1 and p2, __np_anyptrlt(p1,p2) evaluates to:
  • non-zero if p1 and p2 point within the same object and p1 is less than p2
  • zero if p1 and p2 point within the same object and p1 is greater than p2
  • an unspecified integer value if the pointers don't point within the same object or if they compare equal.
A naive implementation is ((p1) < (p2)), but according to the Standard, 6.5.9 (N1124 numbering), this results in undefined behavior when p1 and p2 do not point within (or one member past the end of) a single array object. This naive implementation should only be used then by implementors who can ensure that the behaviour is always reasonable in those cases. The actual end value of the expression doesn't matter in those cases though because for distinct objects it's impossible to corrupt memory no matter which direction memmove iterates in.

A C99 approach

This implementation requires C99 VLAs, and, since it uses temporary storage, there is a much greater risk that it will run out of memory with no warning.

#include <stddef.h> /* for size_t */
#include <stdlib.h> /* for memcpy */

void *memmove(void *dest, const void *src, size_t n)
{
    unsigned char tmp[n];
    memcpy(tmp,src,n);
    memcpy(dest,tmp,n);
    return dest;
}

Complete unit, portable C99 in implementation namespace; public domain; past reviewers: none; current reviews: none

References

Personal tools