Как перехватить исключение в случае деления на нуль ( catch(...) не помогает )
try
{
int d = 0;
while( cin >> d )
cout << 10 / d << "\n";
}
catch(...)
{
cout << "division by zero\n";
}
Здравствуйте, Аноним, Вы писали:
А>Как перехватить исключение в случае деления на нуль ( catch(...) не помогает )
А>А>try
А>{
А> int d = 0;
А> while( cin >> d )
А> cout << 10 / d << "\n";
А>}
А>catch(...)
А>{
А> cout << "division by zero\n";
А>}
А>
Деление на нуль — это аппаратное прерывание... Стандартный механизм не перехватывает... Нужно самому генерить исколючение:
class Zero{};
try {
if(d!=0) cout << 10 / d << "\n";
else throw Zero();
}
catch(const Zero &e)
{
cout << "division by zero\n";
}
Вместо пустого класса можно сделать развитый класс (или унаследовать от одного из стандартных) с полями и методами... Тогда можно будет в обработчик передавать информацию о делителе...
Или можно использовать SEH — с помощью него можно ловить прерывания... Некоторые...
Здравствуйте, Аноним, Вы писали:
А>Как перехватить исключение в случае деления на нуль ( catch(...) не помогает )
А>А>try
А>{
А> int d = 0;
А> while( cin >> d )
А> cout << 10 / d << "\n";
А>}
А>catch(...)
А>{
А> cout << "division by zero\n";
А>}
А>
Модель исключений C++ является синхронной и не предназначена для работы с такими
ошибками. Предполагается, что ты сам генерируешь исключения.
Все, написанное далее относится к VC.
Исключение деления на 0 является так называемым структурным исключением (SE).
Для работы с такими исключениями используются специальные ключевые слова __try
__except. Существует возможность транслировать SEH исключения в исключения C++.
Для этого используют функцию _set_se_translator.
В VC catch(...) некорректно перехватывает структурные исключения. Говорят, что
в версии 8 этого уже нет, но я этого проверить сейчас не могу — работаю на 7.1
Лазар
Здравствуйте, Аноним, Вы писали:
А>Как перехватить исключение в случае деления на нуль ( catch(...) не помогает )
А>А>try
А>{
А> int d = 0;
А> while( cin >> d )
А> cout << 10 / d << "\n";
А>}
А>catch(...)
А>{
А> cout << "division by zero\n";
А>}
А>
в винде:
1. Деление на 0 — структурное исключение, генерируемое в общем случае сопроцессором.
2. По дефолту исключения от сопроцессора замаскированны. Для размаскирования можно юзать _controlfp.
3. Для "превращения" структурного исключения в типизированное С++ исключение можно воспользоваться, как уже говорили выше, _set_se_translator для установки своего транслятора и в этом трансляторе генерить свое исключение, которое далее перехватывать.
Example:
// compile with: /EHa
#include <stdio.h>
#include <windows.h>
#include <eh.h>
void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );
int main( void )
{
try
{
_set_se_translator( trans_func );
SEFunc();
}
catch( const std::exception& e )
{
printf( " caught exception - %s.\n",e.what() );
}
}
void SEFunc()
{
int x, y=0;
x = 5 / y;
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp)
{
printf( "Some structured exception occurred.\n" );
throw std::exception("may be division by zero - for more details look at my 'pExp'");
}