Есть ли способ сказать gcc бросать SIGFPE или что-то подобное в ответ на вычисление, которое приводит к NaN
или (-)inf
во времени выполнения, как он был бы для деления на нуль?
Я попробовал -fsignaling-nans
флаг, который, кажется, не помогает.
Почти любая операция с плавающей точкой или функция математической библиотеки, которая выдает NaN на входах, отличных от NaN, должна также сигнализировать об исключении 'invalid operation' для плавающей точки; аналогично, вычисления, которые выдают бесконечность на конечных входах, обычно сигнализируют об исключении 'divide-by-zero' или 'overflow' для плавающей точки. Поэтому вам нужен какой-то способ превратить эти исключения в SIGFPE.
Я подозреваю, что ответ будет сильно зависеть от системы, так как управление ловушками и флагами плавающей точки, скорее всего, обеспечивается платформенной библиотекой C, а не самим gcc. Но вот пример, который работает у меня в Linux. В нем используется функция feenableexcept
из fenv.h
. Определение _GNU_SOURCE
необходимо для объявления этой функции.
#define _GNU_SOURCE
#include <fenv.h>
int main(void) {
double x, y, z;
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
x = 1e300;
y = 1e300;
z = x * y; /* should cause an FPE */
return 0;
}
Оговорка: я думаю, что при некоторых настройках возможно, что исключение фактически не генерируется до следующей операции с плавающей точкой после той, которая (теоретически) должна была его вызвать, поэтому иногда требуется операция с плавающей точкой без операции (например, умножение на 1.0), чтобы вызвать исключение.