1. ホーム
  2. c

[解決済み] memcpy(0,0,0)を実行しても安全であることが保証されているか?

2023-06-06 01:51:05

質問

C言語規格にあまり詳しくないので、ご容赦ください。

規格上、保証されているのかどうか知りたいです。 memcpy(0,0,0) が安全であることが規格で保証されているのか知りたい。

メモリ領域が重なると挙動が不定になるという制約しか見つけられませんでしたが...。

しかし、ここでメモリ領域が重なっていると考えていいのでしょうか?

どのように解決するのですか?

私は C 規格のドラフト版 (ISO/IEC 9899:1999) を持っていますが、その呼び出しについて楽しいことが書かれています。 手始めに、それは (§7.21.1/2) に関して言及しています。 memcpy ということ

として宣言された引数が size_t nはある関数のための配列の長さを指定します。 として宣言された引数が関数の配列の長さを指定する場合、 nはその関数を呼び出す際に値0を持つことができます。このサブセクションの特定の関数の説明で明示的に記述されていない限り このサブセクションの特定の関数の説明の中で、他に明示されていない限り。 ポインタ引数 は、7.1.4で説明されているように、まだ有効な値を持っていなければならない。 . このような呼び出しにおいて 文字列を検索する関数は出現箇所を発見できず,2つの文字列を比較する関数はゼロを返し 文字列を比較する関数はゼロを返し,文字をコピーする関数はゼロをコピーする。 をコピーします。

ここで示された参考文献は、これを指しています。

関数の引数が無効な値である場合(たとえば 関数のドメイン外の値や、プログラムのアドレス空間外のポインタなど。 またはヌルポインタ または、対応するパラメータがconstで修飾されていない場合の変更不可のストレージへのポインタなど。 パラメータがconst-qualifiedでない場合)、または、可変長の引数を持つ関数が期待しない型(昇格後)。 で期待されない型(昇格後)です。 の場合、動作は未定義です。 .

ということは、C言語仕様によると、呼び出しは

memcpy(0, 0, 0)

の結果は、NULLポインタは"無効な値とみなされるため、未定義の動作となります。

とはいえ、もし実際に memcpy というのも、私が思いつく直感的な実装のほとんどは、ゼロバイトをコピーすると言った場合、まったく何もしないからです。