Самоанализ с плавающей точкой в ​​VS2010 — как проверить без взлома?

Я как бы ходил по домам и думал, что нашел решение. Это, безусловно, правильно определяет проблемы, о которых я знаю, но также приводит к необъяснимым сбоям примерно в половине всех тестов системы.

Проблема в том, что наш код должен вызывать код клиента как dll. Мы контролируем наш код, а не клиентов, и опыт показывает, что их код не всегда безупречен. Я защитился от ошибок сегментации, выйдя из программы с четким сообщением о том, что могло бы пойти не так, но у меня также было несколько исключений деления на ноль из кода клиента, которые я хотел бы идентифицировать и затем выйдите.

То, что я хотел сделать, это:

  1. Непосредственно перед запуском dll клиентов, переключение на плавающую точку
    самоанализ.
  2. Запустите клиентский код.
  3. Проверьте на любые проблемы.
  4. Выключите самоанализ для скорости.

Теоретически существует несколько способов сделать это, но многие не работают на 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’ следует использовать только в глобальном масштабе
область действия или область имен

Что на первый взгляд является прямым противоречием.

Итак, мой вопрос:

  1. Документация правильная или предупреждение (я держу пари на предупреждении)?
  2. Есть ли надежный и безопасный способ сделать это?
  3. Должен ли я делать это вообще или это слишком опасно?

1

Решение

Ты пытался

#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 не может изменить уже скомпилированный код.

Итак, ответы:

  1. Оба верны
  2. Да, _controlfp_s
  3. Вам не хватает статуса SSE2, поэтому он по крайней мере неполный
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]