Как поймать, делят на нуль ошибку на C++ Visual Studio 2008 года?

_MSC_VER и возможно _MSC_FULL_VER то, в чем Вы нуждаетесь. Можно также исследовать visualc.hpp в любой недавней установке повышения для некоторых примеров использования.

Некоторые значения для более свежих версий компилятора:

MSVC++ 14.15 _MSC_VER == 1915 (Visual Studio 2017 version 15.8)
MSVC++ 14.14 _MSC_VER == 1914 (Visual Studio 2017 version 15.7)
MSVC++ 14.13 _MSC_VER == 1913 (Visual Studio 2017 version 15.6)
MSVC++ 14.12 _MSC_VER == 1912 (Visual Studio 2017 version 15.5)
MSVC++ 14.11 _MSC_VER == 1911 (Visual Studio 2017 version 15.3)
MSVC++ 14.1  _MSC_VER == 1910 (Visual Studio 2017 version 15.0)
MSVC++ 14.0  _MSC_VER == 1900 (Visual Studio 2015 version 14.0)
MSVC++ 12.0  _MSC_VER == 1800 (Visual Studio 2013 version 12.0)
MSVC++ 11.0  _MSC_VER == 1700 (Visual Studio 2012 version 11.0)
MSVC++ 10.0  _MSC_VER == 1600 (Visual Studio 2010 version 10.0)
MSVC++ 9.0   _MSC_FULL_VER == 150030729 (Visual Studio 2008, SP1)
MSVC++ 9.0   _MSC_VER == 1500 (Visual Studio 2008 version 9.0)
MSVC++ 8.0   _MSC_VER == 1400 (Visual Studio 2005 version 8.0)
MSVC++ 7.1   _MSC_VER == 1310 (Visual Studio .NET 2003 version 7.1)
MSVC++ 7.0   _MSC_VER == 1300 (Visual Studio .NET 2002 version 7.0)
MSVC++ 6.0   _MSC_VER == 1200 (Visual Studio 6.0 version 6.0)
MSVC++ 5.0   _MSC_VER == 1100 (Visual Studio 97 version 5.0)

номер версии выше, конечно, относится к основной версии Вашей Visual Studio, которую Вы видите в о поле, не к году на имя. Полный список может быть найден здесь . Запуск недавно , Visual Studio начнет обновлять свои диапазоны монотонно, означая, что необходимо проверить диапазоны, а не потребовать значения компилятора.

cl.exe /? даст подсказку используемой версии, например:

c:\program files (x86)\microsoft visual studio 11.0\vc\bin>cl /?
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.50727.1 for x86
.....

7
задан Joshua Fox 2 December 2009 в 14:42
поделиться

7 ответов

Предполагая, что вы не можете просто исправить причину кода, генерирующего исключение (возможно, потому что у вас нет исходного кода для этой конкретной библиотеки и, возможно, потому что вы не можете настроить ввод params, прежде чем они вызовут проблему).

Вы должны перепрыгнуть через несколько обручей, чтобы сделать эту работу так, как вы хотите, но это можно сделать.

Сначала вам нужно установить функцию перевода для обработки структурированных исключений, вызвав _set_se_translator () (см. здесь ), затем вы можете проверить код, который вы передали, когда возникает исключение SEH, и вызвать соответствующее исключение C ++.

void CSEHException::Translator::trans_func(
    unsigned int code, 
    EXCEPTION_POINTERS *pPointers)
{
   switch (code)
   {
       case FLT_DIVIDE_BY_ZERO : 
          throw CMyFunkyDivideByZeroException(code, pPointers);
       break;
   }

   // general C++ SEH exception for things we don't need to handle separately....
   throw CSEHException(code, pPointers);
}

Затем вы можете просто перехватить CMyFunkyDivideByZeroException () в C ++ обычным способом.

8
ответ дан 6 December 2019 в 04:58
поделиться

C ++ не обрабатывает деление на ноль как исключение, само по себе.

Цитата Страуструпа:

«низкоуровневые события, такие как арифметические переполнения и разделить на ноль, являются предполагается, что им будет заниматься специальный механизм нижнего уровня, а не исключения. Это позволяет C ++ соответствовать поведение других языков, когда дело доходит до арифметики. Это также позволяет избежать проблемы, которые возникают на конвейерные архитектуры, в которых события такие как делить на ноль асинхронный ».

« Дизайн и развитие C ++ »(Addison Wesley, 1994)

В любом случае исключения никогда не заменяют надлежащую обработку предусловий.

9
ответ дан 6 December 2019 в 04:58
поделиться

Вы можете либо использовать структурированную обработку исключений (используя __try и т. Д.), Либо установить преобразователь структурированного обработчика исключений: _set_se_translator

Оба они зависят от операционной системы.

7
ответ дан 6 December 2019 в 04:58
поделиться

Вы не можете сделать это, используя стандартный C ++, так как это не стандартное исключение C ++. Это структурированное исключение. Для стандартного исключения C ++ кто-то должен сделать исключение выброса ; из кода.

4
ответ дан 6 December 2019 в 04:58
поделиться

Почему бы не проверить это раньше? Производительность будет тривиальной для простого j == 0 по сравнению с переключением контекста для обработки исключений.

3
ответ дан 6 December 2019 в 04:58
поделиться

Попробуйте следующий код:

try
{ 
  const int j=0;
  if (j == 0) { throw std::exception("j was 0"); } 
  const int i= 1/j;    
}
catch(std::exception& e)
{ 
  printf("%s %s\n", e.what());  
}
catch(...)
{ 
  printf("generic exception"); 
}

Конечно, если у вас все в порядке, без исключений, вы можете сделать:

const int j = 0;
if (j == 0)
{
  /* do something about the bad pre-condition here */
}
else
{
  const int i = 1 / j;
}

Редактировать в ответ на разъяснения: вам нужно будет вычислить выяснить, какие входные данные вы передаете третьей стороне, которая заставляет их заранее делить на ноль, и обрабатывать их, прежде чем вызывать их функцию.

2
ответ дан 6 December 2019 в 04:58
поделиться

Хорошим подходом было бы использование безопасных объектно-ориентированных оболочек, таких как SafeInt . Он также кажется интегрированным в Visual Studio 2010.

обновление:
Если деление на ноль происходит в стороннем коде, ваш единственный вариант - SEH или что-то подобное, как ответил Себ Роуз

1
ответ дан 6 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: