reinterpret_cast
がchar*
(またはchar[N]
)の場合、定義された動作はどのような場合ですか?私はこの質問に答えるために使用すべき親指のルールは何ですか?reinterpret_cast、char *、および未定義の動作
我々はthis questionから学んだように、次は未定義の動作です:
alignas(int) char data[sizeof(int)];
int *myInt = new (data) int; // OK
*myInt = 34; // OK
int i = *reinterpret_cast<int*>(data); // <== UB! have to use std::launder
しかし、どの時点で我々はchar
アレイ上reinterpret_cast
を行うと、それは未定義の動作にすることはできませ持つことができますか? int
開始のために生涯をしたとき
alignas(int) char data[sizeof(int)];
*reinterpret_cast<int*>(data) = 42; // is the first cast write UB?
int i = *reinterpret_cast<int*>(data); // how about a read?
*reinterpret_cast<int*>(data) = 4; // how about the second write?
int j = *reinterpret_cast<int*>(data); // or the second read?
:
ん
new
、ちょうどreinterpret_cast
:ここではいくつかの簡単な例ですか?それはdata
の宣言とそれですか?もしそうなら、寿命はいつ終わるのですかdata
?ポインタが
data
の場合はどうなりますか?char* data_ptr = new char[sizeof(int)]; *reinterpret_cast<int*>(data_ptr) = 4; // is this UB? int i = *reinterpret_cast<int*>(data_ptr); // how about the read?
私はちょうどワイヤ上の構造体を受信し、条件付きで最初のバイトが何であるかに基づいて、それらをキャストしたいんですか?
// bunch of handle functions that do stuff with the members of these types void handle(MsgType1 const&); void handle(MsgTypeF const&); char buffer[100]; ::recv(some_socket, buffer, 100) switch (buffer[0]) { case '1': handle(*reinterpret_cast<MsgType1*>(buffer)); // is this UB? break; case 'F': handle(*reinterpret_cast<MsgTypeF*>(buffer)); break; // ... }
これらのケースのUBのいずれかいますか?それらのすべてですか?この質問に対する答えはC++ 11からC++ 1zに変更されますか?
**(1)**は有効です。どちらのステートメントでも、新しい 'int'オブジェクトが作成され、値が割り当てられます。 *読んで*その価値は物事が毛むくじゃくするところです。 **(2)**と同じです( 'sizeof(int)== 4'と仮定します)。 **(3)**は私にUBのように見えます。 –
@IgorTandetnikあまりにも読んで質問を洗い出し、 'sizeof(int)'についての前提をなくしました。ありがとう。 – Barry
** **(1)**と**(2)**はリンクされた質問と同じ理由でUBを表示するようです。最初のキャストからポインタを保存し、後続のすべての書き込みと読み取りにポインタを使用することで、簡単に回復できます。 –