C標準はそれについて非常に明確です。によって指定されたオブジェクトの有効なタイプはp
、void*
宣言されたタイプであるため、です。を参照してください6.5/6
。C99のエイリアシング規則は読み取りと書き込みに適用され、の左辺値をvoid*
介した書き込みは、によると未定義の動作です。unsigned
(1)
6.5/7
対照的に、任意のオブジェクト()をエイリアスできるため、 memcpy
of(2)
は問題ありません。規格は次のように定義していますunsigned char*
6.5/7
memcpy
7.21.2/1
この節のすべての関数について、各文字はunsigned char型であるかのように解釈されます(したがって、すべての可能なオブジェクト表現は有効であり、異なる値を持ちます)。
memcpy関数は、s2が指すオブジェクトからs1が指すオブジェクトにn文字をコピーします。オーバーラップするオブジェクト間でコピーが行われる場合、動作は定義されていません。
ただし、p
後で使用する場合は、ビットパターンによっては未定義の動作が発生する可能性があります。そのような使用が起こらない場合、そのコードはCで問題ありません。
私の意見では、この問題についてははっきりとは言えないC ++標準によると、次のことが当てはまると思います。この解釈を唯一の可能性としてとらえないでください-漠然とした/不完全な仕様は推測の余地をたくさん残します。
タイプの位置合わせが適切でない可能性があるため、線(1)
に問題があります。に格納されているオブジェクトのタイプをに変更します。後でそのオブジェクトにアクセスしない限り、エイリアシングルールは破られませんが、アライメント要件は破られる可能性があります。&p
unsigned
p
unsigned int
p
ただし、 Lineには配置の問題がないため、後で(2)
アクセスしない限り有効です。これにより、型が格納されたビットパターンをどのように解釈するかによって、未定義の動作が発生する可能性があります。それによってオブジェクトの種類が変わるとは思いません。p
void*
void*
長いGCCバグレポートがあり、そのようなキャストから生じたポインターを介した書き込みの影響と、配置構文の違いは何ですか(そのリストの人々はそれが何であるかについて同意していません)。