厳密なエイリアシング(特に "What is the strict aliasing rule?"と "Strict aliasing rule and 'char *' pointers")については多くの議論がありますが、これは明示的に対処されていないコーナーケースです。C++ 11での厳密なエイリアシングでは、char *に_write_、エイリアスの非文字*から_read_に定義されていますか?
は、このコードを考えてみましょう:
int x;
char *x_alias = reinterpret_cast<char *>(&x);
x = 1;
*x_alias = 2; // [alias-write]
printf("x is now %d\n", x);
は、印刷された値は、[別名 - 書き込み]の変更を反映する必要がありますか? (明らかにエンディアンと表現考慮事項がありますが、それはここに私の心配はありません。)
C++ 11の仕様は、この言語(強調鉱山)を使用しての有名な[basic.lval]句:
は、If
...
- ...様々な他の条件:プログラムは、動作が定義されていない次のいずれかのタイプ以外のglvalueを通してアクセスオブジェクトの格納された値に試みまたは
unsigned char
タイプ。
Iは(のnonchar物体上に文字を書く)「アクセス」のみ(のnoncharオブジェクトから文字を読み取る)読み出し動作したり、また書込み動作を指すかどうかを把握することはできません。スペックに「アクセス」という正式な定義がある場合、私はそれを見つけることができませんが、他の場所では、スペックは読み取りのための「アクセス」と書き込みのための「更新」を使用するようです。
これは、デシリアライズ時に特に重要です。 charバッファからオブジェクトへの中間のmemcpy()を必要とせずに、データをワイヤからオブジェクトに直接渡すことは便利で効率的です。
ありがとうございます!この解釈をバックアップする参考資料はありますか? (例えば、スペックは私が見逃したどこかの "アクセス"を定義していますか?多くの場所で、 "読む"だけを意味するためにその単語を使用しているようです。) –
Aha、見つけました。 "3.1アクセス<実行時のアクション>オブジェクトの値を変更または変更することができます。 –
もちろん、両方のポインタで参照されるアドレスに本当に 'AliasedType'が宣言されている場合にのみ定義されます。すなわち、あなたは 'AliasedType'を宣言し、それにバイトを読み込み、それを読むことができます。しかし、 'unsigned char'の配列を宣言することはできませんし、バイトを読み込み、前に存在しなかったときにそのアドレスから' AliasedType'をマジックアップします。 –