117

memmove()実際に移動/コピーするものがない場合、またはmemcpy()エッジケースとしてケースを処理する必要がありますか?

int numberOfBytes = ...
if( numberOfBytes != 0 ) {
    memmove( dest, source, numberOfBytes );
}

または、チェックせずに関数を呼び出す必要があります

int numberOfBytes = ...
memmove( dest, source, numberOfBytes );

前のスニペットのチェックは必要ですか?

4

2 に答える 2

159

C99標準(7.21.1 / 2)から:

として宣言された引数がsize_t n関数の配列の長さを指定するn場合、その関数の呼び出しで値をゼロにすることができます。この節の特定の関数の説明で特に明記されていない限り、7.1.4で説明されているように、そのような呼び出しのポインタ引数は引き続き有効な値を持っている必要があります。このような呼び出しでは、文字を検索する関数は出現を検出せず、2つの文字シーケンスを比較する関数はゼロを返し、文字をコピーする関数はゼロ文字をコピーします。

したがって、答えはノーです。チェックは必要ありません(またははい。ゼロを渡すことができます)。

于 2010-09-20T13:32:11.930 に答える
6

@Youが言ったように、標準では、memcpyとmemmoveがこのケースを問題なく処理する必要があると指定されています。彼らは通常、何らかの形で実装されているので

void *memcpy(void *_dst, const void *_src, size_t len)
{
    unsigned char *dst = _dst;
    const unsigned char *src = _src;
    while(len-- > 0)
        *dst++ = *src++;
    return _dst;
}

関数呼び出し以外のパフォーマンスのペナルティさえあってはなりません。コンパイラがそのような関数の組み込み関数/インライン化をサポートしている場合、チェックはすでにしばらくの間行われているため、追加のチェックによってコードが少し遅くなることさえあります。

于 2010-09-20T13:33:08.080 に答える