reinterpret_cast, char * y comportamiento indefinido
¿Cuáles son los casos dondereinterpret_cast
ing achar*
(ochar[N]
) es un comportamiento indefinido, y ¿cuándo es un comportamiento definido? ¿Cuál es la regla general que debería usar para responder esta pregunta?
Como aprendimos deesta pregunta, el siguiente es un comportamiento indefinido:
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
Pero en qué punto podemos hacer unreinterpret_cast
en unchar
matriz y NO tiene un comportamiento indefinido? Aquí hay algunos ejemplos simples:
Nonew
, sóloreinterpret_cast
:
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?
¿Cuándo es la vida de laint
¿comienzo? ¿Es con la declaración dedata
? Si es así, ¿cuándo dura la vida dedata
¿fin?
Y sidata
fueron un puntero?
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?
¿Qué sucede si solo recibo estructuras en el cable y quiero emitirlas condicionalmente según el primer byte?
// 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;
// ...
}
¿Alguno de estos casos es UB? Son todos ellos? ¿La respuesta a esta pregunta cambia entre C ++ 11 a C ++ 1z?