Исключние и деление на нуль
От: Аноним  
Дата: 07.09.06 11:58
Оценка:
Как перехватить исключение в случае деления на нуль ( catch(...) не помогает )
try
{
  int d = 0;
  while( cin >> d )
    cout  << 10 / d << "\n";
}
catch(...)
{
  cout << "division by zero\n";
}
Re: Исключние и деление на нуль
От: LaptevVV Россия  
Дата: 07.09.06 12:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как перехватить исключение в случае деления на нуль ( 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 — с помощью него можно ловить прерывания... Некоторые...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Исключние и деление на нуль
От: Лазар Бешкенадзе СССР  
Дата: 07.09.06 15:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как перехватить исключение в случае деления на нуль ( 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

Лазар
Re: Исключние и деление на нуль
От: Andrew_D  
Дата: 07.09.06 19:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как перехватить исключение в случае деления на нуль ( 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'");
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.