reinterpret_cast, char * e comportamento indefinido
Quais são os casos em quereinterpret_cast
ing achar*
(ouchar[N]
) é um comportamento indefinido e quando é um comportamento definido? Qual é a regra geral que devo usar para responder a esta pergunta?
Como aprendemos comessa questão, o seguinte é um comportamento 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
Mas em que momento podemos fazer umareinterpret_cast
com umchar
matriz e NÃO tem um comportamento indefinido? Aqui estão alguns exemplos simples:
Nãonew
, somentereinterpret_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?
Quando é que a vida útil doint
começar? É com a declaração dedata
? Nesse caso, quando é que a vida útil dedata
fim?
E sedata
foi um ponteiro?
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?
E se eu estiver apenas recebendo estruturas na conexão e quiser convertê-las condicionalmente com base no primeiro 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;
// ...
}
Algum desses casos é UB? São todos eles? A resposta a esta pergunta muda entre C ++ 11 e C ++ 1z?