IsoCpp.orgが新たな配置に関するFAQを提供しています:厳格なエイリアシング規則と配置の新
それらが提供する例は次のとおりです。
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
// ...
}
は、上記のコードはplace
ので、C++の厳格なエイリアシング規則に違反しないだろうし、 memory
は異なるタイプですが、同じメモリ位置を参照していますか?
(私はタイプchar
のポインタは、他の型を別名設定できることを知っているが、ここではvoid*
は、私が理解から許可されていないchar*
を、エイリアシング持っているように見える?)
私はそのほとんどのメモリアロケータを疑います同様の方法で厳密なエイリアシング規則に違反します。新しいプレースメントを使用する場合、厳密なエイリアシング規則に準拠する適切な方法は何ですか?
はあなた
標準では、厳密なエイリアシングで 'char'ポインタが実際に免除されています。コンパイラは、さまざまな構造体やその他のものを保持するために頻繁に正確なサイズのバッファを作成するために使用されるため、他のポインタが 'char *'のエイリアスになると仮定する必要があります。 'void *'を参照できないことを考えると、一般的に、コンパイラは、voidポインタを別の型にキャストして使用すると、エイリアスの問題に遭遇する可能性があると不平を言うだけです。あなたの主な問題は 'memory'と' f'エイリアシングですが、 'memory'は' char * 'です。 – RyanP
@RyanP、説明のおかげで;私は厳密なエイリアシングにはまったく新しいので、実際にUBを呼び出すためには逆参照する必要があることを認識していませんでした。私は 'char *'エイリアシング免除について認識していましたが、 'char *'はエイリアス(およびderef)型の 'T'を意味しますが、' T'だけエイリアスとderef 'T *'自体が 'char *'型であれば 'char *'型ですか? – digitale