Отключить исключение с бесконечностью и NaN - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть огромный проект (не созданный мной), который может иметь значения Infinity и NaN. Хотя это разрешено, это не желательно. Я прочитал , что эти значения генерируются такими операциями:

1/0 = ∞
log (0) = -∞
sqrt (-1) = NaN

и, кроме того, когда они достигнуты, должен быть брошен FP Exception.

Если мой проект позволяет выполнять операции с NaN и Infinity, я думал, что SIGFPE будет где-то обрабатываться, но я искал весь проект и не смог его найти.

Есть ли другой способ отключить это исключение? Моя цель состоит в том, чтобы быть в состоянии обнаружить первое появление таких значений.

EDIT: Я использую Windows и намереваюсь включить сигнал, но прежде чем включить, я бы хотел понять, отключился ли он.

1 Ответ

0 голосов
/ 09 ноября 2018

Я думаю, что у вас не будет проблем, о которых вы говорите. По умолчанию исключение FP не возникает. Из документации по Windows :

По умолчанию в системе отключены все исключения FP. Следовательно, вычисления приводят к NAN или INFINITY, а не к исключению. Прежде чем вы сможете перехватывать исключения с плавающей точкой (FP), используя структурированные обработка исключений, вы должны вызвать библиотеку времени выполнения _controlfp_s C функция, чтобы включить все возможные исключения FP. Только в ловушку конкретные исключения, используйте только флаги, которые соответствуют исключения будут в ловушке. Обратите внимание, что любой обработчик ошибок FP должен вызовите _clearfp в качестве первой инструкции FP. Эта функция очищает исключения с плавающей точкой.

То же самое верно и для GCC, где документация гласит:

Когда возникают исключения (когда возникают исключения, на языке стандарт), может произойти одно из двух. По умолчанию исключение просто отмечается в слове состояния с плавающей точкой, и программа продолжается, как будто ничего не случилось. Операция выдает значение по умолчанию значение, которое зависит от исключения [...]). Ваша программа может проверить слово состояния, чтобы узнать, какие исключения произошли.

Чтобы включить исключения (которые остановят выполнение вашей программы) в вашей среде Windows, вы можете попробовать что-то вроде

#include <float.h>

int main() {
    _clearfp();
    unsigned int current_word = 0;
    _controlfp_s(&current_word, ~_EM_ZERODIVIDE, _MCW_EM);
    double div = 0.;
    double f = 1. / div;
}

Для неблокирующих решений попробуйте использовать fenv.h, как описано здесь на cppreference.com.

...