The feenableexcept
function is a linux function that is not part of standard C or POSIX. There is no portable way to enable SIGFPE
.
In fact, you need different code to enable SIGFPE
on the iOS simulator and on iOS devices, because the simulator runs x86 and the device runs ARM.
I think (but have not tested) that you can enable SIGFPE
by getting an fenv_t
using the fegetenv
function, turning some bits on or off in the fenv_t
, and then passing it to the fesetenv
function. The definition of fenv_t
is processor-specific. Take a look at fenv.h
.
For ARM, fenv_t
contains a field named __fpscr
. This is the floating point status and control register. The bits you are allowed to toggle are enumerated in fenv.h
as __fpscr_trap_invalid
, __fpscr_trap_divbyzero
, etc. Presumably you want to turn on the __fpscr_trap_divbyzero
bit.
For x86, fenv_t
contains two fields of interest: __control
(the x87 control word) and __mxcsr
(the SSE control/status register).
The bits you can toggle in __control
are defined by the FE_INEXACT
, FE_UNDERFLOW
, etc. constants defined in fenv.h
. I think you have to turn the bits off to enable SIGFPE
for those exceptions. Check the processor manual, §8.1.5.
The bits you can toggle in __mxcsr
are defined by the _MM_MASK_INVALID
, __MM_MASK_DENORM
, etc. constants in xmmintrin.h
. I think that you need to turn the bits off to enable SIGFPE
. Check the processor manual, §10.2.3.
fenv_t fe;
if (fegetenv(&fe) != 0) {
// error
}
#if defined __arm__
fe.__fpscr |= __fpscr_trap_divbyzero;
#elif defined __i386__
fe.__control &= ~FE_DIVBYZERO;
fe.__mxcsr &= ~_MM_MASK_DIV_ZERO;
#else
#error unknown processor architecture
#endif
if (fesetenv(&fe) != 0) {
// error
}
You may also need to do #pragma STDC FENV_ACCESS ON
for all processors.
Again, I haven't tested any of this. Good luck.