memmoveの実装方法

ISO/IEC 9899 ではmemmoveについて以下のように書かれているようです。(C99でもC11でも)

C

1#include <string.h>2void *memmove(void *s1, const void *s2, size_t n);

The memmove function copies n characters from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2, and then the n characters from the temporary array are copied into the object pointed to by s1.

https://www.open-std.org/jtc1/sc22/wg14/www/projects

s1にもs2にも重なり合わない一時領域にs2をコピーしてからs1にコピーするようです。
s1とs2のアドレスを比較して、前また後ろからコピーすればいいと思うのですが、なぜわざわざ一時領域にコピーする必要があるのでしょうか。

検索してみると、下記のようにアドレスを比較して実装しているものが多く出てくるのですが、これは規格に従っていない関数ということになるのでしょうか。

C

1void *memmove(void *dest, const void *src, size_t size)2{3 uint8_t *d = dest;4 const uint8_t *s = src;5 size_t i;6 7 if (d < s) {8 for (i = 0; i < size; ++i)9 d[i] = s[i];10 } else if (d > s) {11 i = size;12 while (i-- > 0)13 d[i] = s[i];14 }15 16 return dest;17}18

https://github.com/freebsd/freebsd-src/blob/main/sys/contrib/xz-embedded/linux/lib/decompress_unxz.c

また、こちらのサイト
http://libc.blog47.fc2.com/blog-entry-38.html
では(httpsではないので開く時に注意が出るかもしれません)、

「型が同じでも異なるポインタは、比較できない処理系がある」

と書かれています。ポインタの比較は処理系定義ということでしょうか。
CPUによってはポインタの比較ができない場合があり、処理系定義となっているのでしょうか。

コメントを投稿

0 コメント