reinterpret_cast, char * e comportamento indefinido

Quais são os casos em quereinterpret_casting 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?

questionAnswers(1)

yourAnswerToTheQuestion