1

2 つの質問があります。1 つはポインターの型操作全般に関する一般的な質問で、もう 1 つは私が持っている特定のケースに関する質問です。

異なる型のポインタを使用してメモリのバッファにアクセスするとどうなりますか?

多くの異なるコンパイラで実際に実行してみると、私の脳が想像した通りに動作するようですただし、多くの場合(すべてではないにしても)UBであることはある程度知っています。例えば:

typedef unsigned char byte;
struct color { /* stuff */};

std::vector<color> colors( 512 * 512 );
// pointer of one type
color* colordata = colors.data();
// pointer to another type?
byte* bytes = reinterpret_cast<byte*>( colordata );

// Proceed to read from (potentially write into) 
// the "bytes" of the 512 * 512 heap array

最初の質問は次のとおりです。この種の変換を行うことが合法/安全/標準で認可されているポイントはありますか?

struct2 番目の質問:名前付きが次のcolorように定義されていることがわかっている場合は、最初の質問をスピンオフします。

 struct color { byte c[4]; };

さて、それは合法/安全/標準認可ですか? 読み取り安全?読み取り/書き込みは安全ですか? 私の直感では、これらの非常に単純な構造体の場合、上記のいたずらなポインター操作はそれほど悪くないことがわかります。

[ 再度開く理由: ] 厳密なエイリアシングに関するリンクされた質問はここでは多少当てはまりますが、ほとんどは C に関するものです。C++03 標準を参照する 1 つの回答は、C++11 標準と比較すると時代遅れになる可能性があります (まったく何も変更されていない場合を除きます)。 )。この質問には実用的なアプリケーションがあり、私や他の人はより多くの回答を得ることができます. 最後に、この質問は、読み取りセーフ、書き込みセーフ、またはその両方ではないか (またはどちらでもないか)、および 2 つの異なるシナリオ (基になる型が一致する PoD データと、任意の内部データのより一般的なケース) であるかどうかを尋ねる非常に具体的な質問です。 )。

4

2 に答える 2

5

どちらも合法です。

まず、byteは の typedef であるためunsigned char、厳密なエイリアシングに関しては魔法のように脱獄できます。char任意の型を、署名付きまたは署名なしの派生物のいずれかとしてエイリアスできます。

第 2 に、構造体が POD であるなどの特定の保証を満たしている限り、最初の要素の型へのポインターにキャストすることは、C と C++ の両方で完全に合法です。この意味は

struct x {
    int f;
};
int main() {
    x var;
    int* p = (int*)&var;
}

に使用される getout 句がなくても、厳密なエイリアシングに違反しませんchar

于 2013-07-13T02:47:25.290 に答える
3

コメントで述べられているように: 2 つの異なる型として同じメモリにアクセスすることは UB です。したがって、これが正式な回答です (「UB」には、「コードを読んでいる正気な人が期待することを正確に実行する」ことと、「コードを読んでいる正気な人が期待すること以外のほぼすべてのこと」が含まれることに注意してください)。 )

そうは言っても、一般的なコンパイラはすべて、これにかなりうまく対処する傾向があるようです。この種の構成要素が見られることは珍しくありません (「優れた」製品コードでは、コードが厳密に言語法に準拠していなくても)。ただし、「正しいことをしている」コンパイラに翻弄されており、物事を厳しく強調しすぎると、コンパイラのバグが見つかる可能性があることは間違いありません。

標準がこれを UB として定義する理由はいくつかあります。主な理由は、「さまざまな種類のデータがさまざまなメモリに格納される可能性がある」ことと、「誰かがキャストをいじっているときに、コンパイラが何が安全かを判断するのが難しい場合がある」ことです。異なる型の同じデータへのポインター" - たとえば、32 ビット整数へのポインターと char への別のポインターがあり、どちらも同じアドレスを指している場合、char 値が読み取られた後に整数値を読み取ることが安全なのはいつですか?書いた。これを UB として定義することにより、これらの条件をどの程度正確に処理するかを決定するのは完全にコンパイラ ベンダー次第です。これが機能することが「定義」されていた場合、コンパイラは特定のプロセッサ タイプでは実行できない可能性があります (または、「

つまり、要約すると、ほとんどのプロセッサで動作する可能性が高いですが、言語弁護士がコードを承認することを期待しないでください。

于 2013-05-08T10:39:57.517 に答える