Когда математическая функция обнаруживает ошибку, она засылает некоторое значение переменной errno. В зависимости от степени значимости ошибки, она также может напечатать сообщение в stderr. Это поведение не является реентерабельным. Когда некий процесс фиксирует ошибку, он изменяет значение errno. Если какой-то другой процесс тестирует errno, он обнаруживает изменение и останавливается. Помните, что остановка системы сама также может переопределить значение errno. Эту проблему можно решить либо игнорированием errno, либо рассмотрением ее как части самого процесса и переключением ее вместе с остальной частью процессора. В нормальной отлаженной программе как правило не возникает ошибок математических подрпограмм - и, вследствие этого,- нет вызовов matherr; в этой ситуации математические функции способны к реентрабельности.
В качестве альтернативных Вы можете использовать рекуррентные версии тех же математических функций : они имеют другие названия, обычно образованные добавлением '_' к началу идентификатора и '_r' в конец, и требуют еще один аргумент - указатель на частную структуру двойного вхождения. Обратитесь к разделу "Reentrancy" в Cygnus C Support Library, для получения помощи по этому вопросу.
Структура повторного вхождения всегда предполагает дополнительный первый аргумент; например реентерабельная версия функции 'double acos(double x)' будет 'double _acos_r (void *reent, double x)'.
Ниже приведен список названий для реентрабельных версий функций из математической библиотеки :
_acos_r _gammaf_r_r _log10f_r
_acosf_r _hypot_r _log_r
_acosh_r _hypotf_r _logf_r
_acoshf_r _j0_r _pow_r
_asin_r _j0f_r _powf_r
_asinf_r _j1_r _remainder_r
_atan_r _j1f_r _sinh_r
_atanf_r _jn_r _sinhf_r
_cosh_r _jnf_r _sqrt_r
_coshf_r _ldexp_r _sqrtf_r
_exp_r _ldexpf_r _y0_r
_expf_r _lgamma_r _y0f_r
_fmod_r _lgamma_r_r _y1_r
_fmodf_r _lgammaf_r _y1f_r
_gamma_r _lgammaf_r_r _yn_r
_gamma_r_r _log10_r _ynf_r
_gammaf_r