Перехват исключения при делении на 0

203
22 июля 2018, 05:40

Пытаюсь отловить исключение через catch/try:

void TestCall()
{
    int b=0;
    try
    {
        int a = 1/b;        
    }
    catch(...)
    {
        test(1);
    }
}

Выражение int a = 1/b; заведомо вызывает исключение деления на 0 и я хоч его поймать в блоке catch. Но Visual C++ упорно вызывает ошибку на нем и на catch не перекидывает. В чем секрет?

Answer 1

Вы путаете исключения С++ и прочие исключения. В С++ исключения возникают исключительно при использовании оператора throw. Деление на 0 при использовании встроенного оператора / является неопределенным поведением:

8.6 Multiplicative operators [expr.mul]

4 The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined.

Answer 2

В Windows деление на ноль генерирует исключение SEH с кодом STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000094). Чтобы обрабатывать его в стиле исключений С++, можно установить в Visual C++ параметр компилятора /EHa, или установить фильтр необработанных исключений:

#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <exception>
#include <windows.h>
LONG WINAPI UnhandledExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo){
    if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_INTEGER_DIVIDE_BY_ZERO)
        throw std::exception("STATUS_INTEGER_DIVIDE_BY_ZERO");  
    return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR* argv[])
{   
    SetUnhandledExceptionFilter(&UnhandledExceptionFilter); 
    int b=0;
    try
    {
        int a = 1/b;        
    }
    catch(std::exception ex)
    {       
        printf("Exception: %s\n",ex.what());
    }   
    return 0;
}

(Второй способ работает только при запуске без отладки, так как отладчик студии принудительно прерывает программу на SEH-исключениях.)

READ ALSO
MSVS/MSVC function alias

MSVS/MSVC function alias

Попытки повторить аналог поведения __attribute__ ((alias ("realfunc"))) из GCC в MSVS/MSVC успехом не закончилисьЧто не так? и есть ли решения на базе pragma, macro?

195
Отличия в заголовках и их приемущества stdint-gcc.h и cstdint

Отличия в заголовках и их приемущества stdint-gcc.h и cstdint

Хотелось бы узнать в чем разница данных подключений, и в чем особенность каждого из stdint-gcch и cstdint, т

199
Синтаксис cpp (exception ntdll.dll) [дубликат]

Синтаксис cpp (exception ntdll.dll) [дубликат]

На данный вопрос уже ответили:

189
Не распознается тип фрагмента

Не распознается тип фрагмента

У меня есть класс WorkoutDetailFragment, который наследуется от FragmentВ скрипте пытаюсь вернуть ссылку на этот фрагмент, но возникает следующая ошибка:

166