2011-01-19 15 views
4

私は私のコードでは、このような何かを持っている場合:同じアドレスのC構造割当は有効ですか?

void f(struct foo *x, struct foo *y) 
{ 
    *x = *y; // structure copy (memcpy?) 
} 

同じアドレスにxとyのポイントは、どのような問題が発生した場合は?

この有効なコードであり、コンパイラが代入を無効なオペランドの可能性のあるmemcpyコールに変換する場合(オーバーラップできない場合)はどうなりますか?

[はい、この場合は「制限」を使用できますが、これを考慮した実際のコードはbisonによって自動的に生成されるため、常に有効かどうか、またコンパイラmemmoveなどを使用する必要がありますオーバーラップ..]

答えて

0

[はい、私は標準のビットを見た後にこれを見たように自分の質問に答えると、ここに関連する質問は難しく検索]

実は、これはthis answerに(Are there any platforms where using structure copy on an fd_set (for select() or pselect()) causes problems?への回答の一部で答えています)、私はここに貼り付けるれる:以下の

一つは、保持しなければならない。

...

左オペランドは、AQを持っています権利の種類と互換性のある構造体または共用体型のualified版またはunqualified版。

...

オブジェクトに格納された値がどのように最初のオブジェクトのストレージに重なる他のオブジェクトから読み取られた場合、重なりが正確でなければならず、2つのオブジェクトが修飾又はていなければなりません互換性のある型の非修飾バージョン。それ以外の場合、動作は未定義です。

したがって、ポインタが同じ(つまり、全体的なオーバーラップ)限り、これは問題ありません。コンパイラが、memcpyの仕様にもかかわらず、重複が許されていないにもかかわらず、時にはこのためにmemcpyを呼び出すことが奇妙に思えます。おそらく、コンパイラは、ドキュメンテーションを逃すよりも、memcpyの特定の実装についてもっと知っているかもしれません。

1

これは私に完全に有効に見えます。はい、これは一種のmemcpyになります。

structのような2つのポインタは、同じであるか、まったく重ならないようにする必要があります。ポインタが等しいかどうかをチェックすることができます。

(あなたは確かに本当の重複を持っているあなたのコードをだますことができますが、それを行うには本当に特別な理由があるように必要があると思います。)

+0

チェックをする必要はありません。 –

+0

downvote、vow。 –

3

構造の割り当ては完全に合法です。したがって、コンパイラは正しいコードを生成します(コンパイラのバグにもかかわらず)。

0

これは有効なコードです。コンパイラはx!= yとすることはできませんので、安全なmemmoveを使用する必要があります。

+1

また、memcpyがその場合に有効であることを知っておいてください。memcpyのほとんどの実装では部分的な重なりはあるが、重複のある部分は問題になる可能性があります。 * x = * yは、準拠しているコードで部分的に重複することはありません。 – AProgrammer

関連する問題