Как перехватить исключения системного уровня в Linux C ++? - PullRequest
4 голосов
/ 06 марта 2009

Следующая функция catch () не вызывается:

void test(void)
{
    int i=1,j=0,k;
    try
    {
        k = i/j;
    }
    catch(...)
    {
        ...handle it...
    }
}

Есть ли способ отловить такого рода исключения?

Ответы [ 3 ]

8 голосов
/ 06 марта 2009

Пожалуйста, проверьте http://linux.die.net/man/1/gcc для этого есть опция компилятора -mcheck-zero-Division.

В качестве альтернативы, установка обработчика SIGFPE может быть вариантом, Затем деление с плавающей точкой на 0 сгенерирует «FPE_ZERODIVIDE»

         signal(SIGFPE, (fptr) FPE_ExceptionHandler);

         void FPE_ExceptionHandler(int nSig,int nErrType,int */*pnReglist*/)
          {
                switch(nErrType)
                  {
                    case FPE_ZERODIVIDE:  /* ??? */ break;
                }

            }

с

Большинство систем с плавающей запятой основаны на стандарте IEEE, который допускает деление на 0. Это возвращает либо положительную бесконечность, либо отрицательную бесконечность, в зависимости от ситуации, на основе знаков чисел. (За исключением 0/0 возвращает неопределенный NAN - опять-таки не исключительный случай.) Это имеет тенденцию быть полезным для научных и математических приложений. NAN эффективно сигнализируют о случае, когда вычисления не были возможны, но позволяют вычислениям продолжаться. Продолжение расчетов не даст новых результатов, но будет продолжать возвращать NAN. Это позволяет выполнять длинные длинные цепочки вычислений без проверки ошибок в пределах вычислений. Проверки ошибок необходимо выполнять только в самом конце работы. Это делает код намного проще и быстрее. Иногда это может быть более полезным, так как для некоторых приложений инфинитизм является «полезным» результатом, а не признаком проблем.

3 голосов
/ 06 марта 2009

Если это вообще вызывает ошибку во время выполнения (см. Хорошее обсуждение lakshmanaraj по математике IEEE , хотя какой-то компилятор позволит вам принудительно использовать ошибки вместо NaN), он выдает исключение с плавающей запятой сигнал .

Сигналы представляют собой механизм, отличный от исключений в c ++, и обрабатываются на уровне ОС. Уже есть ряд вопросов SO относительно механизма сигналов * nix, в том числе:

Для окон вам придется попросить кого-то еще. Mac OS X, конечно же, является производной от Unix системой.

3 голосов
/ 06 марта 2009

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

...