Code snippets:portable memmove
From C
Many memmove attempts attempt to compare s1 and s2 with a relational operator such as < or >. Unfortunately, however, this is not really portable. In C99, for example, 6.5.8p5 implies that if the relational operators are used with objects that are not sub-objects (including sub-sub-objects, and so on) of the same ultimate parent object, then the behaviour is undefined.
/* Shao Miller, 2012 */ #include <stdio.h> #include <stdlib.h> void * pmemcpy(void * s1, const void * s2, size_t n); void * pmemmove(void * s1, const void * s2, size_t n); int main(void) { char test1[] = "0123456789"; char test2[] = "ABCDEFGHIJ"; char * t1; char * t2; t1 = pmemmove(test1, test1 + 5, 5); t2 = pmemmove(test2 + 5, test2, 5); (void) t2; printf("%s\n%s\n", t1, test2); return EXIT_SUCCESS; } void * pmemcpy(void * s1, const void * s2, size_t n) { unsigned char * dest; const unsigned char * src; if (!s1 || !s2 || !n) return s1; dest = s1; src = s2; while (n--) *dest++ = *src++; return s1; } /* Portability wins over performance, here */ void * pmemmove(void * s1, const void * s2, size_t n) { unsigned char * dest; const unsigned char * src; const unsigned char * src_end; if (!s1 || !s2 || !n || s1 == s2) return s1; dest = s1; src = s2; /* The only interesting case is where src < dest with overlap */ for (src_end = src + n; src < src_end; ++src) { if (src == dest) break; } /* Is src > dest or non-overlapping? */ if (src == src_end) return pmemcpy(s1, s2, n); /* Otherwise, src < dest with overlap */ dest += n; src = src_end; while (n--) *dest-- = *src--; return s1; }