Я как бы ходил по домам и думал, что нашел решение. Это, безусловно, правильно определяет проблемы, о которых я знаю, но также приводит к необъяснимым сбоям примерно в половине всех тестов системы.
Проблема в том, что наш код должен вызывать код клиента как dll. Мы контролируем наш код, а не клиентов, и опыт показывает, что их код не всегда безупречен. Я защитился от ошибок сегментации, выйдя из программы с четким сообщением о том, что могло бы пойти не так, но у меня также было несколько исключений деления на ноль из кода клиента, которые я хотел бы идентифицировать и затем выйдите.
То, что я хотел сделать, это:
Теоретически существует несколько способов сделать это, но многие не работают на VS2010.
Я пытался использовать прагму с плавающей точкой:
#pragma float_control(except, on, push)
// run client code
#pragma float_control(pop)
__asm fwait; // This forces the floating point unit to synchronise
if (_statusfp() & _SW_ZERODIVIDE)
{
// abort the program
}
Это должно быть хорошо в теории, и на практике это работает хорошо в 50% случаев.
Я думаю, что проблема может быть в том, что элемент управления с плавающей точкой остается включенным и вызывает проблемы в других частях кода.
По данным microsoft.com:
«/ Fp: точный, / fp: быстрый, / fp: строгий и / fp: кроме управления переключателями
Семантика с плавающей запятой для каждого файла отдельно. Float_control
Прагма обеспечивает такой контроль для каждой функции «.
Однако во время компиляции я получаю предупреждение:
предупреждение C4177: #pragma ‘float_control’ следует использовать только в глобальном масштабе
область действия или область имен
Что на первый взгляд является прямым противоречием.
Итак, мой вопрос:
Ты пытался
#pragma float_control(except, on, push)
// run client code
#pragma float_control(pop)
Это не так, как это работает. Это директива компилятора, и это означает,
#pragma float_control(except, on, push)
// This entire function is compiled with float_control exceptions on.
// Therefore, the pragma has to appear outside the function, at global scope.
#pragma float_control(pop)
И, конечно, этот параметр влияет только на компилируемую функцию (-и), никакие функции, которые они могут вызывать, такие как ваши клиенты. #Pragma не может изменить уже скомпилированный код.
Итак, ответы:
_controlfp_s
Других решений пока нет …