Почему не работает фильтр исключений?
От: Studentus  
Дата: 24.08.06 10:35
Оценка:
Есть код:


#include "stdafx.h"
#include <iostream>

void foo()throw()
{
    new double[0xfffffff];    
}

int _tmain(int argc, _TCHAR* argv[])
{
    try{
    for(int i = 0; i < 20; i++)
        foo();
    }
    catch (std::bad_alloc) {
        std::cout << "bad::alloc";
    }
    return 0;
}


компилю. запускаю.
на выходе в консоли: bad_alloc
Объясните плизз дураку почему?
разве:
void foo()throw()
не должно блокировать выход любых исключений наружу?
Re: Почему не работает фильтр исключений?
От: KBH  
Дата: 24.08.06 10:46
Оценка: 2 (1)
Пустая спецификация исключений дает гарантии пользователю того что функция не генерит исключения. А если все-таки происходит генерация, и в списке такого исключения нет, то вызывается пользовательская unexpected(), если есть, иначе вызывается terminate(), который тоже можно подменить. А terminate() в итоге вызывает abort().
Re: Почему не работает фильтр исключений?
От: Centaur Россия  
Дата: 24.08.06 10:49
Оценка: 2 (1)
Здравствуйте, Studentus, Вы писали:

S>разве:

S>void foo()throw()
S>не должно блокировать выход любых исключений наружу?

Должно, путём пристреливания всей программы через terminate() в случае нарушения спецификации исключений. Но Microsoft Visual C++ их игнорирует.
Re: Почему не работает фильтр исключений?
От: Ulfur Россия  
Дата: 24.08.06 10:50
Оценка: 2 (1) -2
Здравствуйте, Studentus, Вы писали:

S>Есть код:



S>
S>#include "stdafx.h"
S>#include <iostream>

S>void foo()throw()
S>{
S>    new double[0xfffffff];    
S>}

S>int _tmain(int argc, _TCHAR* argv[])
S>{
S>    try{
S>    for(int i = 0; i < 20; i++)
S>        foo();
S>    }
S>    catch (std::bad_alloc) {
S>        std::cout << "bad::alloc";
S>    }
S>    return 0;
S>}

S>


S>компилю. запускаю.

S>на выходе в консоли: bad_alloc
S>Объясните плизз дураку почему?
S>разве:
S>void foo()throw()
S>не должно блокировать выход любых исключений наружу?

В твоем случае стандартом обещан UB. Пользуясь твоей спецификацией исключений ты говоришь компилятору, что твоя функция не будет кидать исключений, а никак не "блокируешь" исключения, тем более что блокировать ты их никак не сможешь, только поймать .
Re[2]: Почему не работает фильтр исключений?
От: Studentus  
Дата: 24.08.06 10:56
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Должно, путём пристреливания всей программы через terminate() в случае нарушения спецификации исключений. Но Microsoft Visual C++ их игнорирует.


Блин похоже на правду (gcc 3.3.3 так себя и ведет, а вот MSVS 2003 нет), а жаль
мне показалось, что фильтр гарантирует, что вообще ничего не ружу не прорвется
а как же тогда себя обезопасить на 100% от выкидыванися эксепшна?
Re[3]: Почему не работает фильтр исключений?
От: Roman Odaisky Украина  
Дата: 24.08.06 11:35
Оценка:
Здравствуйте, Studentus, Вы писали:

S>мне показалось, что фильтр гарантирует, что вообще ничего не ружу не прорвется

S>а как же тогда себя обезопасить на 100% от выкидыванися эксепшна?

Ну как же,
try
{
    somethingDangerous();
}
catch(...)
{
    // It hasn't worked, and we'll never know why...
}

Можешь дефайн сделать для такого.
До последнего не верил в пирамиду Лебедева.
Re[4]: Почему не работает фильтр исключений?
От: Studentus  
Дата: 24.08.06 12:03
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


S>>мне показалось, что фильтр гарантирует, что вообще ничего не ружу не прорвется

S>>а как же тогда себя обезопасить на 100% от выкидыванися эксепшна?

RO>Ну как же,

RO>
RO>try
RO>{
RO>    somethingDangerous();
RO>}
RO>catch(...)
RO>{
RO>    // It hasn't worked, and we'll never know why...
RO>}
RO>

RO>Можешь дефайн сделать для такого.

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

Понятно, что можно извратиться макросами... , но это не так красиво
Re: Почему не работает фильтр исключений?
От: don ASKet Россия  
Дата: 24.08.06 13:34
Оценка: 2 (1)
Здравствуйте, Studentus, Вы писали:

1. фильтр исключений работает на ура. std::alloc он и отсекает. Правда конечно токо у Мелкомягких. у остальных вообще до этого дело не дойдет, ибо прога вылетит в std::unexсepted()...
Мне кажется что ты немного попутал термины:
фильтр исключений у тебя в строке catch (std::bad_alloc) { — он фильтрует, какие исключения попадут в обработчик исключений в котором он задан.
а то что у тебя не работает, строка — void foo() throw() — это спецификация исключений — СИ (exception specifications). Которая всего — лишь деклалирует какие эксепшны функция может выкидывать. Генерация же других, должна по стандрату приводит к последовательности вызовов: std::unexcepted() -> std::terminate() -> std::abort(). Но это только по умолчанию

2. имхо, в С++ спецификация исключений — СИ не несет каких-либо плюсов. Вот если бы она работала как ты хотел. Тогда можно было бы подумать, об ее использовании.
Чаще всего СИ используется, для указания стороннему разработчику, что данная функция помимо стандартных исключений может кинуть дополнительные, ну или производные от них. Но это же можно отлично прописать и просто комментом, не маясь в последствии с std::unexcepted()....

Так что, имхо, лучше писать:
voif foo(); //throw(MyException)

и инфа есть, и никаких неожиданностей не будет
Меняю два проигрывателя, на один выигрватель! Возможна доплата... ;)
Re[2]: Почему не работает фильтр исключений?
От: Studentus  
Дата: 24.08.06 16:15
Оценка:
Здравствуйте, don ASKet, Вы писали:

DA> к последовательности вызовов: std::unexcepted() -> std::terminate() -> std::abort(). Но это только по умолчанию


а как сделать не по умолчанию?
Re[3]: Почему не работает фильтр исключений?
От: shank  
Дата: 24.08.06 16:59
Оценка: 3 (1)
Здравствуйте, Studentus, Вы писали:

DA>> к последовательности вызовов: std::unexcepted() -> std::terminate() -> std::abort(). Но это только по умолчанию


S>а как сделать не по умолчанию?

Установить свои обработчики для unexpected или terminate.
Вот как это делается для unexpected (пример из MSDN):
#include<exception>
#include<iostream>

using namespace std;

void unfunction( ) 
{
   cout << "I'll be back." << endl;
   terminate( );
}

int main( ) 
{
   unexpected_handler oldHand = set_unexpected( unfunction );
   unexpected( );
}

Output
I'll be back.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.