#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()
не должно блокировать выход любых исключений наружу?
Пустая спецификация исключений дает гарантии пользователю того что функция не генерит исключения. А если все-таки происходит генерация, и в списке такого исключения нет, то вызывается пользовательская unexpected(), если есть, иначе вызывается terminate(), который тоже можно подменить. А terminate() в итоге вызывает abort().
S>компилю. запускаю. S>на выходе в консоли: bad_alloc S>Объясните плизз дураку почему? S>разве: S>void foo()throw() S>не должно блокировать выход любых исключений наружу?
В твоем случае стандартом обещан UB. Пользуясь твоей спецификацией исключений ты говоришь компилятору, что твоя функция не будет кидать исключений, а никак не "блокируешь" исключения, тем более что блокировать ты их никак не сможешь, только поймать .
Здравствуйте, Centaur, Вы писали:
C>Должно, путём пристреливания всей программы через terminate() в случае нарушения спецификации исключений. Но Microsoft Visual C++ их игнорирует.
Блин похоже на правду (gcc 3.3.3 так себя и ведет, а вот MSVS 2003 нет), а жаль
мне показалось, что фильтр гарантирует, что вообще ничего не ружу не прорвется
а как же тогда себя обезопасить на 100% от выкидыванися эксепшна?
Здравствуйте, Studentus, Вы писали:
S>мне показалось, что фильтр гарантирует, что вообще ничего не ружу не прорвется S>а как же тогда себя обезопасить на 100% от выкидыванися эксепшна?
Ну как же,
try
{
somethingDangerous();
}
catch(...)
{
// It hasn't worked, and we'll never know why...
}
Здравствуйте, 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>Можешь дефайн сделать для такого.
ну эт понятно ...
просто хотелось бы в объявлении функции уже указать, что пользующий ее человек может дергать ее спокойно, не опасаясь никаких исключений.... Ибо даже если таковые и возникнут, то они из этой функции не выйдут.
А получается, что от этой спецификации толку, почти ноль. Ну есть проверка на этапе компиляции подпадения выбрасываемых исключений под спецификацию, но мне этого мало.
Понятно, что можно извратиться макросами... , но это не так красиво
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)
и инфа есть, и никаких неожиданностей не будет
Меняю два проигрывателя, на один выигрватель! Возможна доплата... ;)
Здравствуйте, don ASKet, Вы писали:
DA> к последовательности вызовов: std::unexcepted() -> std::terminate() -> std::abort(). Но это только по умолчанию
Здравствуйте, Studentus, Вы писали:
DA>> к последовательности вызовов: std::unexcepted() -> std::terminate() -> std::abort(). Но это только по умолчанию
S>а как сделать не по умолчанию?
Установить свои обработчики для unexpected или terminate.
Вот как это делается для unexpected (пример из MSDN):