У меня есть некоторые фрагменты кода C++, которые при запуске в Xcode с включенным Undefined Behavior Sanitizer сообщают: «runtime error: store to misaligned address 0x7f8bcc403771 for type 'int', which requires 4 byte alignment
».
Поэтому я создал небольшой тестовый пример Catch2, чтобы воспроизвести код, который мне нужно проверить во время выполнения как на Windows/x64 (MSVC), так и на Mac (Xcode 11/clang), но все работает, как и ожидалось, даже при компиляции с различными типами оптимизации ( -O2, -O3, -Ofast и др.).
Рассматриваемый код (тестовый пример Catch2):
TEST_CASE("misaligned_write", "[demo]") {
unsigned char *data = (unsigned char*)malloc(20);
memset(data, 0, 20);
int *ptr = reinterpret_cast<int*>(&data[1]);
*ptr = 0x11223344; // undefined behaviour triggered
CHECK(static_cast<uint8_t>(data[1]) == 0x44);
CHECK(static_cast<uint8_t>(data[2]) == 0x33);
CHECK(static_cast<uint8_t>(data[3]) == 0x22);
CHECK(static_cast<uint8_t>(data[4]) == 0x11);
}
Итак, мой вопрос: это неопределенное поведение, ложное срабатывание, или в коде есть что-то, что может сломаться в будущем из-за некоторых изменений флагов компилятора по умолчанию?
0x7f8bcc403771 % 4 != 0
. Вот поэтому и жалуется. - person Rietty   schedule 16.10.2019int *ptr = reinterpret_cast<int*>(&data[1]); *ptr = 0x11223344;
это УБ. Вptr
нетint
, поэтому вы не можете записать его. Это может измениться в будущем (об этом есть предложение), но пока это не будет стандартизировано, это UB. - person NathanOliver   schedule 16.10.2019reinterpret_cast
определяется только в том случае, если вы приводите некоторый типA
кB
(но не используете его какB
), а затем обратно кA
. Другие варианты использования — неопределенное поведение. Например, это полезно, когда вам нужно передать данные функции обратного вызова, которая требует от вас приведения ваших данных кvoid *
. Затем внутри обратного вызова вы возвращаете его к исходному типу. - person darcamo   schedule 16.10.2019char *p = new char [10]; delete p;
потерпеть неудачу, но я знаю, чтоdelete p;
— это неопределенное поведение. Почему я это знаю? Потому что стандартный документ сказал нам, что это так. - person PaulMcKenzie   schedule 16.10.2019int int_data = 0x11223344; memcpy(&data[1], &int_data, sizeof int_data);
. Обратите внимание, что существует специфичное для платформы поведение в отношении порядка байтов и размера int; Я предполагаю, что эти вещи не имеют значения для вашего варианта использования. - person Eljay   schedule 16.10.2019__attribute__((packed))
) вместоreinterpret_cast
, активирует ли это также UBsan? - person rustyx   schedule 16.10.2019