В каких случаях reinterpret_cast
выполнение char*
(или char[N]
) является неопределенным поведением, а когда это определенное поведение? Какое эмпирическое правило я должен использовать, чтобы ответить на этот вопрос?
Как мы узнали из этого вопроса, следующее поведение undefined:
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
Но в какой момент мы можем сделать reinterpret_cast
на массиве char
и НЕ иметь неопределенного поведения? Вот несколько простых примеров:
Нет
new
, простоreinterpret_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?
Когда начинается срок службы
int
? Это с объявлением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?
int
и ему присваивается значение. Чтение этой ценности - вот где начинаются неприятности. То же самое с (2) (при условииsizeof(int)==4
). (3) для меня выглядит как UB. - person Igor Tandetnik   schedule 10.09.2016sizeof(int)
, спасибо. - person Barry   schedule 10.09.2016language-lawyer
. ; -] - person ildjarn   schedule 11.09.2016int
объекта вdata
илиdata_ptr
. - person T.C.   schedule 12.09.2016