C++ Standart exceptions
От: Handler Украина  
Дата: 05.11.11 16:29
Оценка: :)
Здравствуйте!
Нужна Ваша консультация по исключениям.
Приведу несколько типов исключений:
try {
// uncatched 
1) std::cout << *(int*)(0);
2) int* p; *(p)=10;
3) int i=10/0;
4) vector<int> v; v[10]=10;
5) char* с = new char[2]; c[22]='a';

// catched 
6) vector<int> v; v.at(10)=10;
}
catch(exception& e){
std::cout<<e.what();
exit(EXIT_FAILURE);
}

Первый тип "неуловимых" исключений мы поймать не можем. Почему? И если все-таки можем, то как?
Второй тип исключений ловится нормально, т.е. мы должны заранее "подготовить почву" под исключение, но мы не можем просто ловить исключения в блоке программы.
Больше всего меня беспокоит 5 пример: такой код в Маке и Винде вообще не вызовет исключения, программа может писать куда угодно что угодно в пределах своей "кучи". Исключение возникнет только в Линукс.
Теперь вопрос: Как правильно организовать обработку исключений для кроссплатформенного приложения?
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
Re: C++ Standart exceptions
От: LaptevVV Россия  
Дата: 05.11.11 17:13
Оценка:
Здравствуйте, Handler, Вы писали:

H>Здравствуйте!

H>Нужна Ваша консультация по исключениям.
H>Приведу несколько типов исключений:
H>
H>try {
H>// uncatched 
H>1) std::cout << *(int*)(0);
H>2) int* p; *(p)=10;
H>3) int i=10/0;
H>4) vector<int> v; v[10]=10;
H>5) char* с = new char[2]; c[22]='a';

H>// catched 
H>6) vector<int> v; v.at(10)=10;
H>}
H>catch(exception& e){
H>std::cout<<e.what();
H>exit(EXIT_FAILURE);
H>}

H>Первый тип "неуловимых" исключений мы поймать не можем. Почему? И если все-таки можем, то как?
H>Второй тип исключений ловится нормально, т.е. мы должны заранее "подготовить почву" под исключение, но мы не можем просто ловить исключения в блоке программы.
H>Больше всего меня беспокоит 5 пример: такой код в Маке и Винде вообще не вызовет исключения, программа может писать куда угодно что угодно в пределах своей "кучи". Исключение возникнет только в Линукс.
H>Теперь вопрос: Как правильно организовать обработку исключений для кроссплатформенного приложения?
Стандартные С++ исключения — это языковый механизм, предоставляемый программисту.
С++ "ловит" только те исключения, которые явно генерированы оператором throw.
Аппаратные аварийные прерывания возникают "самостоятельно". Некоторые из них (например, деление на ноль) программист
может "предвосхитить", явно проверяя делитель и прописав в программе оператор throw.
Но в большинстве случаев обработка аппаратных исключений — платформенно-зависимо.
Поэтому надо выделить обработку исключений в некую отдельную подсистему. Которую и переписывать для каждой системы.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.11.11 17:40
Оценка: 1 (1)
Здравствуйте, Handler, Вы писали:

H>Здравствуйте!

H>Нужна Ваша консультация по исключениям.
H>Приведу несколько типов исключений:
H>
H>try {
H>// uncatched 
H>1) std::cout << *(int*)(0);
H>2) int* p; *(p)=10;
H>3) int i=10/0;
H>4) vector<int> v; v[10]=10;
H>5) char* с = new char[2]; c[22]='a';

H>// catched 
H>6) vector<int> v; v.at(10)=10;
H>}
H>catch(exception& e){
H>std::cout<<e.what();
H>exit(EXIT_FAILURE);
H>}

H>Первый тип "неуловимых" исключений мы поймать не можем. Почему? И если все-таки можем, то как?
Можем. Обращение по нулевому адресу под Win сгенерирует SEH исключение, которое ловится __catch (вроде) — это расширение MSVC, Но вроде и catch(...) его поймает.

H>Второй тип исключений ловится нормально, т.е. мы должны заранее "подготовить почву" под исключение, но мы не можем просто ловить исключения в блоке программы.

Не факт. p может указывать куда угодно, хотя, по идее, он должен быть инициализирован нулем, и следовательно goto 1.

3е — на перечисленных платформах сгенерируется аппаратное исключение, но в общем случае тоже не факт.
4ое — не факт. Оператор [] должен быть быстрым, и, особенно в релизе, может не проверять индекс. Для гарантированной проверки надо использовать at().

H>Больше всего меня беспокоит 5 пример: такой код в Маке и Винде вообще не вызовет исключения, программа может писать куда угодно что угодно в пределах своей "кучи". Исключение возникнет только в Линукс.

Странно, почему в линуксе возникает исключение. Компилятор (gcc?) делает проверку индекса при простом обращении к памяти? Нафик такой компилятор, это же тормозить должно. Или там в конце каждого блока некий длинный гуард блок?

H>Теперь вопрос: Как правильно организовать обработку исключений для кроссплатформенного приложения?

Как обычно. То, что вы перечислили, это просто грубые ошибки, которых не следует допускать. Их может отловить система (а не C++), но не факт.
Маньяк Робокряк колесит по городу
Re: C++ Standart exceptions
От: whitewin  
Дата: 05.11.11 19:41
Оценка:
Здравствуйте, Handler, Вы писали:

H>5) char* с = new char[2]; c[22]='a';


H>Больше всего меня беспокоит 5 пример: такой код в Маке и Винде вообще не вызовет исключения, программа может писать куда угодно что угодно в пределах своей "кучи". Исключение возникнет только в Линукс.


А какой дистрибутив Linux и какой компилятор использовались, и с какими флагами компиляции?
Re[2]: C++ Standart exceptions
От: Handler Украина  
Дата: 05.11.11 22:05
Оценка: :))
H>>5) char* с = new char[2]; c[22]='a';

W>А какой дистрибутив Linux и какой компилятор использовались, и с какими флагами компиляции?


Я работаю на Маке gcc 4.2.1 и делаю тестовую работу. Мой проверяющий сказал, что на Линукс — это приведет к ошибке
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
Re[3]: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.11.11 22:20
Оценка: :)
Здравствуйте, Handler, Вы писали:

H>>>5) char* с = new char[2]; c[22]='a';


W>>А какой дистрибутив Linux и какой компилятор использовались, и с какими флагами компиляции?


H>Я работаю на Маке gcc 4.2.1 и делаю тестовую работу. Мой проверяющий сказал, что на Линукс — это приведет к ошибке


Поставьте ему двойку и скажите, что зачет он не сдаст. Пусть побегает за вами для пересдачи, а не сдаст — пусть берет академку и возвращается через год. Приведенный код будет работать думаю на всех архитектурах без каких-либо run-time исключений (exceptions), но результат его работы не определен.
Маньяк Робокряк колесит по городу
Re: C++ Standart exceptions
От: Centaur Россия  
Дата: 06.11.11 07:00
Оценка:
Здравствуйте, Handler, Вы писали:

H>Здравствуйте!

H>Нужна Ваша консультация по исключениям.
H>try {
H>// uncatched 
H>1) std::cout << *(int*)(0);
H>2) int* p; *(p)=10;
H>3) int i=10/0;
H>4) vector<int> v; v[10]=10;
H>5) char* с = new char[2]; c[22]='a';

Здесь нет ни одного оператора, который бы был должен по стандарту выбрасывать исключение. 1) разыменование нулевого указателя, 2) разыменование неинициализированного указателя, 3) деление на нуль, 4) обращение к элементу вектора за пределами его размера, 5) обращение к элементу массива за пределами его размера — это всё неопределённое поведение. Неопределённое поведение может принимать гораздо более интересные и причудливые формы, чем выброс исключения.

H>// catched 
H>6) vector<int> v; v.at(10)=10;
H>}

Здесь поведение определено. vector<T>::at() при попытке обращения к невалидному индексу выбрасывает std::out_of_range.

А кроме того, прошедшее время от глагола catch — caught.
Re[2]: C++ Standart exceptions
От: Handler Украина  
Дата: 06.11.11 07:45
Оценка:
За урок англицкого отдельное спасибо (пардон, catch — неправильный глагол?).
Из обсуждения я вынес следующие вещи:
Существуют 3 типа исключений:
1. Аппаратные(деление на ноль) — не ловятся ничем
2. Стандартные (разыменование ноля) — ловятся через опции компилятора.
3. програмные (vector.at()) — ловятся стандартными методами исключений

То есть не существует единой програмной ловушки, заворачивающей все исключения?
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
Re[3]: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 06.11.11 08:17
Оценка:
Здравствуйте, Handler, Вы писали:

H>За урок англицкого отдельное спасибо (пардон, catch — неправильный глагол?).

H>Из обсуждения я вынес следующие вещи:
H>Существуют 3 типа исключений:
H>1. Аппаратные(деление на ноль) — не ловятся ничем
H>2. Стандартные (разыменование ноля) — ловятся через опции компилятора.
H>3. програмные (vector.at()) — ловятся стандартными методами исключений

Ерунда какая.
Что за стандартные исключения?
Исключения могут быть только программные и аппаратные, зависит от того, генерируются они апаратурой или софтом. Ловятся они всегда софтом, будь то прикладной софт или ОС. Если не ловятся, то это , как правило, остановка или крах системы.
То, что вы классифицировали как стандартное исключение — это аппаратное или системное исключение (генерирует ОС/железо). И оно не поймается через опции компилятора.
В контексте C++ можно рассматривать исключения системные и языковые. Системные — это разыменование нуля, деление на ноль, запись в "левую" память. В общем случае платформа может и не генерировать их, и тогда вы о них и не узнаете.
Языковые — это исключения, которые генерируются средствами языка, и ими же перехватываются. Язык, в общем случае, может и не иметь механизма исключений. Для C++ он есть — throw/try/catch.

H>То есть не существует единой програмной ловушки, заворачивающей все исключения?

Нет. Для ловли системных исключений есть __try/__catch (MSVC/Win), или сигналы (Unix/POSIX).
Маньяк Робокряк колесит по городу
Re[4]: C++ Standart exceptions
От: LaptevVV Россия  
Дата: 06.11.11 08:54
Оценка:
Здравствуйте, Marty, Вы писали:

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


H>>За урок англицкого отдельное спасибо (пардон, catch — неправильный глагол?).

H>>Из обсуждения я вынес следующие вещи:
H>>Существуют 3 типа исключений:
H>>1. Аппаратные(деление на ноль) — не ловятся ничем
H>>2. Стандартные (разыменование ноля) — ловятся через опции компилятора.
H>>3. програмные (vector.at()) — ловятся стандартными методами исключений

M>Ерунда какая.

M>Что за стандартные исключения?
M>Исключения могут быть только программные и аппаратные, зависит от того, генерируются они апаратурой или софтом. Ловятся они всегда софтом, будь то прикладной софт или ОС. Если не ловятся, то это , как правило, остановка или крах системы.
M>То, что вы классифицировали как стандартное исключение — это аппаратное или системное исключение (генерирует ОС/железо). И оно не поймается через опции компилятора.
M>В контексте C++ можно рассматривать исключения системные и языковые. Системные — это разыменование нуля, деление на ноль, запись в "левую" память. В общем случае платформа может и не генерировать их, и тогда вы о них и не узнаете.
M>Языковые — это исключения, которые генерируются средствами языка, и ими же перехватываются. Язык, в общем случае, может и не иметь механизма исключений. Для C++ он есть — throw/try/catch.
Вы хотели сказать "прерывания". Так как описываете именно прерывания. А исключения — это языковое понятие, а не платформенное или аппаратное.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 06.11.11 09:17
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

LVV>Вы хотели сказать "прерывания". Так как описываете именно прерывания. А исключения — это языковое понятие, а не платформенное или аппаратное.

Ну, это зависит от терминологии. В архитектуре Intel это вроде все же называется исключениями. Но даже если вы правы, то винда генерирует системное исключение по этим прерываниям.
Маньяк Робокряк колесит по городу
Re[5]: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 06.11.11 09:18
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Вы хотели сказать "прерывания". Так как описываете именно прерывания. А исключения — это языковое понятие, а не платформенное или аппаратное.

Ну и в догонку — в POSIX это действительно выглядит и работает как прерывания — дергаются обработчики сигналов.
Маньяк Робокряк колесит по городу
Re[5]: C++ Standart exceptions
От: Кодт Россия  
Дата: 06.11.11 09:22
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Вы хотели сказать "прерывания". Так как описываете именно прерывания. А исключения — это языковое понятие, а не платформенное или аппаратное.


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

Кстати, иногда прерываниями называют только сигналы, приходящие извне процессора (в том числе, от внешнего менеджера памяти, как в моторолах 68000, емнип), а исключениями — только то, что порождает сам процессор (его подсистема управления памятью, привилегиями, а также исполнение соответствующих инструкций).
А иногда валят в кучу и аппаратные, и программные прерывания — поскольку реакция процессора на них одинаковая: переключение контекста и вызов функции-обработчика.

Опять же, с позиций конечного пользователя, не всякое срабатывание защиты памяти является исключением. Например, это обращение к странице, которая зарезервирована, но не размещена (новая либо вытесненная в своп).
Перекуём баги на фичи!
Re[6]: C++ Standart exceptions
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 06.11.11 09:32
Оценка:
Здравствуйте, Кодт, Вы писали:

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


К>Ай, это терминологические споры.

Вообщем да, вы как обычно все разложили по полочкам

ЗЫ С возвращением. Без вас тут (в разделе C++) грустновато было
Маньяк Робокряк колесит по городу
Re[7]: C++ Standart exceptions
От: Кодт Россия  
Дата: 06.11.11 12:02
Оценка:
Здравствуйте, Marty, Вы писали:

M>ЗЫ С возвращением. Без вас тут (в разделе C++) грустновато было

Да я тут так... набегами. Когда хочется мозг размять
Перекуём баги на фичи!
Re[4]: C++ Standart exceptions
От: sidorov18 США  
Дата: 07.11.11 13:25
Оценка:
Здравствуйте, Marty, Вы писали:

H>>То есть не существует единой програмной ловушки, заворачивающей все исключения?

M>Нет. Для ловли системных исключений есть __try/__catch (MSVC/Win), или сигналы (Unix/POSIX).

Я не знаю, как на других платформах, но для SEH можно установить \EHa флаг(в студии находится в C/C++ -> Code Generation).
В этом случае все будет ловится в try/catch блоках.


    try
    {
        int d = 0;
        int a = 1 / d;
    }
    catch (...)
    {
        cout << "exception" << endl;
    }
Re: C++ Standart exceptions
От: PanychY  
Дата: 09.11.11 16:57
Оценка:
Здравствуйте, Handler, Вы писали:

H>Здравствуйте!

H>Нужна Ваша консультация по исключениям.
H>Приведу несколько типов исключений:

О, старый знакомый. Я Вам на lafox-е ответил
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.