Деление на 0
От: Аноним  
Дата: 03.12.05 05:44
Оценка:
#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    try
    {
       int p=0;
       int i=5/p;
    }
    catch (...)
    {
       cout<<"Error";
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}


Не отрабатывается деление на 0. Как побороть? Спасибо.
Re: Деление на 0
От: Centaur Россия  
Дата: 03.12.05 07:11
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    try
А>    {
А>       int p=0;
А>       int i=5/p;
А>    }
А>    catch (...)
А>    {
А>       cout<<"Error";
А>    }
А>


А>Не отрабатывается деление на 0. Как побороть? Спасибо.


Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.

#include <stdexcept>
#include <string>
#include <iostream>
#include <ostream>

int checked_divide(int numerator, int denominator)
{
  if (0 == denominator) throw std::domain_error("Division by zero");
  return numerator / denominator;
}

int main()
{
  try
  {
    int p = 0;
    int i = checked_divide(5, p);
  }
  catch (const std::exception& e)
  {
    std::cout << "Error: " << e.what() << std::endl;
  }
}
Re[2]: Деление на 0
От: Аноним  
Дата: 03.12.05 08:09
Оценка:
Понятно. Спасибо.
Re[2]: Деление на 0
От: _const_  
Дата: 03.12.05 09:50
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Здравствуйте, Аноним, Вы писали:



C>Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.


Уверены? У меня на VC6 и VC7 ДЛЯ ЦЕЛОЧИСЛЕННЫХ ТИПОВ стабильно вылетает Exception: Integer Divide by Zero.
Re[3]: Деление на 0
От: CrystaX Россия https://crystax.me/
Дата: 03.12.05 10:08
Оценка:
Здравствуйте, _const_, Вы писали:

C>>Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.


__>Уверены? У меня на VC6 и VC7 ДЛЯ ЦЕЛОЧИСЛЕННЫХ ТИПОВ стабильно вылетает Exception: Integer Divide by Zero.


Это не C++ exception. Смотри в сторону Win32 SEH.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Деление на 0
От: _const_  
Дата: 03.12.05 10:36
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Это не C++ exception. Смотри в сторону Win32 SEH.


А разве в случае выполнения арифметических операций могло быть исключение C++? Вопрос-то был: почему не вылетает исключение вообще, какое бы то ни было?
Re[5]: Деление на 0
От: CrystaX Россия https://crystax.me/
Дата: 03.12.05 10:49
Оценка:
Здравствуйте, _const_, Вы писали:

CX>>Это не C++ exception. Смотри в сторону Win32 SEH.


__>А разве в случае выполнения арифметических операций могло быть исключение C++?


Нет, не могло. Если касаться только и исключительно C++, то деление на 0 — UB, как правильно заметил Centaur. Конкретно в среде MS VC++ это UB выражается выбрасыванием SEH исключения, которое никакого отношения к C++ не имеет. Но в UNIX, например, это уже будет посылка сигнала процессу, который его (процесс) убьет, если не принять дополнительных действий.

__> Вопрос-то был: почему не вылетает исключение вообще, какое бы то ни было?


Если же брать конкретный случай, описываемый автором, то необходима дополнительная информация — для начала операционная система, компилятор и ключи компиляции.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[6]: Деление на 0
От: Аноним  
Дата: 03.12.05 11:14
Оценка:
Здравствуйте, CrystaX, Вы писали:



CX>Если же брать конкретный случай, описываемый автором, то необходима дополнительная информация — для начала операционная система, компилятор и ключи компиляции.


WinXP Home SP2, MinGW, Dev-C++. Default установки.
Re[2]: Деление на 0
От: Аноним  
Дата: 03.12.05 11:17
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.


А если нет возможности предотвращения? Как это дело вообще можно обработать?
Re[3]: Деление на 0
От: Аноним  
Дата: 03.12.05 11:20
Оценка:
Здравствуйте, _const_, Вы писали:

__>Здравствуйте, Centaur, Вы писали:


C>>Здравствуйте, Аноним, Вы писали:



C>>Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.


__>Уверены? У меня на VC6 и VC7 ДЛЯ ЦЕЛОЧИСЛЕННЫХ ТИПОВ стабильно вылетает Exception: Integer Divide by Zero.


Event Type: Error
Event Source: Application Error
Event Category: None
Event ID: 1000
Date: 03.12.2005
Time: 12:25:27
User: N/A
Computer: QA
Description:
Faulting application test.exe, version 1.0.0.1, faulting module test.exe, version 1.0.0.1, fault address 0x00003285.

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Data:
0000: 41 70 70 6c 69 63 61 74 Applicat
0008: 69 6f 6e 20 46 61 69 6c ion Fail
0010: 75 72 65 20 20 74 65 73 ure tes
0018: 74 2e 65 78 65 20 31 2e t.exe 1.
0020: 30 2e 30 2e 31 20 69 6e 0.0.1 in
0028: 20 74 65 73 74 2e 65 78 test.ex
0030: 65 20 31 2e 30 2e 30 2e e 1.0.0.
0038: 31 20 61 74 20 6f 66 66 1 at off
0040: 73 65 74 20 30 30 30 30 set 0000
0048: 33 32 38 35 0d 0a 3285..

Event Type: Error
Event Source: Application Error
Event Category: None
Event ID: 1000
Date: 03.12.2005
Time: 12:23:00
User: N/A
Computer: QA
Description:
Faulting application test.exe, version 1.0.0.1, faulting module mfc42d.dll, version 6.0.8168.0, fault address 0x00082f8e.

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Data:
0000: 41 70 70 6c 69 63 61 74 Applicat
0008: 69 6f 6e 20 46 61 69 6c ion Fail
0010: 75 72 65 20 20 74 65 73 ure tes
0018: 74 2e 65 78 65 20 31 2e t.exe 1.
0020: 30 2e 30 2e 31 20 69 6e 0.0.1 in
0028: 20 6d 66 63 34 32 64 2e mfc42d.
0030: 64 6c 6c 20 36 2e 30 2e dll 6.0.
0038: 38 31 36 38 2e 30 20 61 8168.0 a
0040: 74 20 6f 66 66 73 65 74 t offset
0048: 20 30 30 30 38 32 66 38 00082f8
0050: 65 0d 0a e..
Re[6]: Деление на 0
От: _const_  
Дата: 03.12.05 11:22
Оценка:
Здравствуйте, CrystaX, Вы писали:


CX>Нет, не могло. Если касаться только и исключительно C++, то деление на 0 — UB, как правильно заметил Centaur. Конкретно в среде MS VC++ это UB выражается выбрасыванием SEH исключения, которое никакого отношения к C++ не имеет. Но в UNIX, например, это уже будет посылка сигнала процессу, который его (процесс) убьет, если не принять дополнительных действий.


Не совсем понял, как VC может выбрасывать исключения. Мое понимание таково. При обнаружении аппаратной ошибки в виде деления на ноль Windows бросает соответствующее исключение. Ловить его или нет — проблема программиста. При этом некоторые необработанные исключения (access violation) приведут к аварийному завершению программы (а-ля UNIX), а некоторые — нет. Хотя второе утверждение спорно: возможно, некоторые исключения ловятся стандартной библиотекой или что-то в этом роде.



CX>Если же брать конкретный случай, описываемый автором, то необходима дополнительная информация — для начала операционная система, компилятор и ключи компиляции.


Согласен. Кстати, при Release компиляции пример действительно перестал падать.
Re[3]: Деление на 0
От: Аноним  
Дата: 03.12.05 11:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Centaur, Вы писали:


C>>Деление на 0 — это undefined behavior, а не исключительная ситуация. Его нельзя обработать, его можно только предотвратить.


А>А если нет возможности предотвращения? Как это дело вообще можно обработать?


__try
{
...
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
...
}
Re[4]: Деление на 0
От: Аноним  
Дата: 03.12.05 11:41
Оценка:
А>__try
А>{
А>...
А>}
А>__except(EXCEPTION_EXECUTE_HANDLER)
А>{
А>...
А>}

14 C:\Dev-Cpp\Project\main.cpp `__try' undeclared (first use this function)
Re[7]: Деление на 0
От: CrystaX Россия https://crystax.me/
Дата: 03.12.05 11:54
Оценка:
Здравствуйте, _const_, Вы писали:

__>Не совсем понял, как VC может выбрасывать исключения. Мое понимание таково. При обнаружении аппаратной ошибки в виде деления на ноль Windows бросает соответствующее исключение. Ловить его или нет — проблема программиста. При этом некоторые необработанные исключения (access violation) приведут к аварийному завершению программы (а-ля UNIX), а некоторые — нет. Хотя второе утверждение спорно: возможно, некоторые исключения ловятся стандартной библиотекой или что-то в этом роде.


Исключение выбрасывает не VC, это верно. Вот только преобразовывает SEH в C++ исключение MS CRT library. Поэтому ты можешь поймать любое SEH исключение, преобразовав его к C++ exception. Подробнее — _set_se_translator. Но все это действует только при условии использования MS CRT, почему и было написано о среде MS VC++.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[5]: Деление на 0
От: Cyberax Марс  
Дата: 03.12.05 12:23
Оценка:
_const_ wrote:

> CX>Это не C++ exception. Смотри в сторону Win32 SEH.

> А разве в случае выполнения арифметических операций могло быть
> исключение C++? Вопрос-то был: почему не вылетает исключение вообще,
> какое бы то ни было?

Деление на ноль — это UB. То есть программа вправе форматировать винт и
слать боссу письма с порнухой.

Бросание исключения — это просто один из вариантов UB.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[7]: Деление на 0
От: Cyberax Марс  
Дата: 03.12.05 12:28
Оценка:
_const_ wrote:

> Не совсем понял, как VC может выбрасывать исключения. Мое понимание

> таково. При обнаружении аппаратной ошибки в виде деления на ноль
> Windows бросает соответствующее исключение. Ловить его или нет —
> проблема программиста.

Windows НЕ бросает исключение С++. Бросается исключение через механизм
SEH (Structured Exception Handling), который от С++ никак не зависит.

SEH-исключение можно преобразовать в С++-исключение, иногда это делается
автоматически. Читайте help на функцию _set_se_translator.

Естественно, к языку С++ это отношения не имеет — это уже особенности
конкретной реализации. В Юниксах, например, будут использоваться сигналы.

> При этом некоторые необработанные исключения (access violation)

> приведут к аварийному завершению программы (а-ля UNIX), а некоторые — нет.

Более того, с помощью механизма SEH можно ловить даже access violation и
продолжать после него работу.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[8]: Деление на 0
От: _const_  
Дата: 03.12.05 12:44
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>_const_ wrote:


>> Не совсем понял, как VC может выбрасывать исключения. Мое понимание

>> таково. При обнаружении аппаратной ошибки в виде деления на ноль
>> Windows бросает соответствующее исключение. Ловить его или нет —
>> проблема программиста.

C>Windows НЕ бросает исключение С++. Бросается исключение через механизм

C>SEH (Structured Exception Handling), который от С++ никак не зависит.

"А я этого и не утверждал" ((c) Петров)

C>SEH-исключение можно преобразовать в С++-исключение, иногда это делается

C>автоматически. Читайте help на функцию _set_se_translator.

Спасибо, читал.

C>Естественно, к языку С++ это отношения не имеет — это уже особенности

C>конкретной реализации. В Юниксах, например, будут использоваться сигналы.

>> При этом некоторые необработанные исключения (access violation)

>> приведут к аварийному завершению программы (а-ля UNIX), а некоторые — нет.

Уточню, имелось в виду, если код не "обернут" в SEH-фрейм.

C>Более того, с помощью механизма SEH можно ловить даже access violation и

C>продолжать после него работу.

Полностью согласен.

C>--

C>С уважением,
C> Alex Besogonov (alexy@izh.com)
Re[6]: Деление на 0
От: Кодт Россия  
Дата: 03.12.05 14:16
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Деление на ноль — это UB. То есть программа вправе форматировать винт и

C>слать боссу письма с порнухой.

TODO: не забыть включить эту ценную фичу в спецификацию. Поднять боссу хмм... настроение.

Кстати говоря, crash report'ы слать — очень даже разумная реализация такого UB.
Перекуём баги на фичи!
Re[7]: Деление на 0
От: Cyberax Марс  
Дата: 03.12.05 15:11
Оценка:
Кодт wrote:

> C>Деление на ноль — это UB. То есть программа вправе форматировать винт и

> C>слать боссу письма с порнухой.
> TODO: не забыть включить эту ценную фичу в спецификацию. Поднять боссу
> хмм... настроение.

Действительно, хорррошая идея...

> Кстати говоря, crash report'ы слать — очень даже разумная реализация

> такого UB.

Ага, еще можно использовать систему WSYP
(http://www.ondotnet.com/pub/wlg/8118)

А если серьезно, то есть полезная тулзы для этого:
http://www.codeproject.com/debug/crash_report.asp
http://www.codeproject.com/debug/XCrashReportPt4.asp

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Деление на 0
От: gear nuke  
Дата: 04.12.05 23:14
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>14 C:\Dev-Cpp\Project\main.cpp `__try' undeclared (first use this function)


2 обходных пути:
  1. Установить SEH фрейм вручную. Для этого понадобится ассемблер.
  2. SetUnhandledExceptionFilter.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.