Я хочу увидеть пример без использования функции RaiseException.
Без , кто , использующий функцию RaiseException? Кто-то должен ... потому что единственный способ получить исключение, перехватываемое конструкцией C ++ (будь то ___ попытка SEH или попытка исключений C ++ ), это если что-то где-то это поднимает.
На аппаратном уровне процессор x86 имеет флаг Alignment Check (AC). Если флаг установлен, тогда прерывание 17 выполняется , когда происходит непривязанный доступ. Но в Windows вы можете перехватить такое прерывание только в режиме ядра .
Если вы хотите, чтобы программа пользовательского режима на С ++ получала исключения, связанные с не выровненным доступом - исходя из врожденной способности процессора наблюдать за выровненным доступом, вам нужно было бы записать это в драйвере устройства. И даже тогда для получения исключения потребуется обратный вызов пользовательского режима, что привело к его повышению.
Для того, чтобы проверить, не могу ли я вызвать какие-либо сбои при плохом выравнивании, я попытался адаптировать некоторые встроенные сборки из этого ответа в MSVC. (Синтаксис MSVC отличается, но я понимаю, что это должно быть сделано ... по крайней мере, сделать последующий pushfd и изучить его с извлеченными локальными переменными, предположив, что бит AC действительно изменяется в процессе):
#include <iostream>
int main() {
__asm {
pushfd
mov eax, [esp]
or eax, 0x40000
mov [esp], eax
popfd
}
char *data = new char[sizeof(int) + 1];
int *p = reinterpret_cast<int*>(data + 1);
*p = 304;
std::cout << *p;
}
Но, похоже, новые ошибки не появляются. Я не могу прочитать регистр cr0 , чтобы увидеть, установлена ли маска выравнивания, она мне не даст (mov eax, cr0
вызывает ошибку «привилегированная инструкция»). И я не знаю, что Windows использует для ответа на прерывание 17 по умолчанию, может быть, нет? Или, скорее всего, программы x86 в 64-битной сборке Windows не обращают на это внимания, но я не могу выполнить 64-битную инструкцию, потому что MSVC не поддерживает встроенную сборку в 64-битной . : - /
Несмотря ни на что, остаётся вопрос: чтобы ваша Win32 C ++ программа получала уведомление через исключение ошибки выравнивания, что-то должно это сказать ... и Windows не настроена реагировать на проблемы выравнивания, замеченные самим процессором. Таким образом, все ваши уведомления будут поступать от таких вещей, как предупреждения компилятора или добавленные пользователем проверки во время выполнения самих значений указателя.