Самоанализ с плавающей запятой в VS2010 — как проверить, не нарушая?

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

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

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

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

Теоретически существует несколько способов сделать это, но многие из них, похоже, не работают для VS2010.

Я пытался использовать прагму float_point:

#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:precise, /fp:fast, /fp:strict и /fp:except управляют семантикой с плавающей запятой для каждого файла. Прагма float_control обеспечивает такой контроль для каждой функции. ."

Однако во время компиляции я получаю предупреждение:

предупреждение C4177: #pragma 'float_control' следует использовать только в глобальной области или области пространства имен

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

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

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

person Mike Sadler    schedule 12.12.2013    source источник
comment
Последний ответ stackoverflow. com/questions/16804519/ на самом деле выглядит так, как будто это может быть полезно (хотя и не объясняет, почему вышеизложенное может не работать)...   -  person Mike Sadler    schedule 12.12.2013


Ответы (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, так что он как минимум неполный
person MSalters    schedule 12.12.2013