Вот вопрос возник: что делает спецификатор исключения, типа:
class My_Class
{
public:
My_Class() throw() {}
~My_Class() throw() {}
void func() throw(Exception) {}
};
Что даёт спецификация исключения? Лично я предпочитаю ставить его везде, где это возможно, хотя бы затем, чтобы явно видеть, какие исключения может сгенерировать метод/функция. Что будет, если метод, помеченный как не генерирующий исключений, его всё таки сгенерирует? Как это сказывается на производительности? Или это несёт только информационную нагрузку для читающего код? Если нет, то хорошего/плохого я от этого получаю? Спасибо.
Здравствуйте, Аноним, Вы писали:
А>Вот вопрос возник: что делает спецификатор исключения, типа:
А>А>class My_Class
А>{
А>public:
А> My_Class() throw() {}
А> ~My_Class() throw() {}
А> void func() throw(Exception) {}
А>};
А>
А>Что даёт спецификация исключения? Лично я предпочитаю ставить его везде, где это возможно, хотя бы затем, чтобы явно видеть, какие исключения может сгенерировать метод/функция. Что будет, если метод, помеченный как не генерирующий исключений, его всё таки сгенерирует? Как это сказывается на производительности? Или это несёт только информационную нагрузку для читающего код? Если нет, то хорошего/плохого я от этого получаю? Спасибо.
Спецификация исключений заставляет компилятор генерировать дополнительный код, проверяющий, что исключения, бросаемые функцией, не нарушают спецификацию, и вызывающий в случае нарушения функцию unexpected():
void func() throw (Exception)
{
…
}
становится
void func()
{
try
{
…
}
catch (const Exception& e)
{
throw;
}
catch (...)
{
unexpected();
}
}
Функция unexpected вызывает обработчик, установленный пользователем через set_unexpected(). Обработчик имеет право:
завершить программу через terminate(),
бросить исключение, допускаемое спецификацией.
Короче говоря:
Moral #1: Never write an exception specification.
Moral #2: Except possibly an empty one, but if I were you I’d avoid even that.
/Herb Sutter, A Pragmatic Look at Exception Specifications
Здравствуйте, Centaur, Вы писали:
C>Короче говоря:
C>Moral #1: Never write an exception specification.
C>Moral #2: Except possibly an empty one, but if I were you I’d avoid even that.
C>/Herb Sutter, A Pragmatic Look at Exception Specifications
Мне кажется спецификация исключений очень хорошая вещь, только недоработанная.
Очень хотелось бы чтобы спецификация исключений была частью интерфейса функции и была полная статическая проверка во время компиляции.
Но пока этого нет, увы, Саттер прав.
Я использую спецификацию исключений везде.
Но использую для нее специальный макрос.
size_t read( void* buf, size_t count) M_THROW(( FILE_ERR_E ));
void close( void ) M_THROW(());
LOG_OBJ_C* log_prs_new_obj(
LOG_OBJ_TYPE_T obj_type,
const LOG_OBJ_FORMAT_T* obj_format,
NET_IN_PACK_C* pack
)
M_THROW(( std::bad_alloc, LOG_MSG_ERR_E, NET_PACK_ERR_E ));
Во время компиляции этот макрос и его содержимое вырезаются.
А вот во время проверки исходного кода специальным тулом (
PC-Lint) заменяются на нормальную спецификацию исключений.
#ifdef MLIB_THROW_SPEC
#define M_THROW( x ) throw x
#else
#define M_THROW( x )
#endif
Тут можно посмотреть на исходный код.
Здравствуйте, Аноним, Вы писали:
А>Вот вопрос возник: что делает спецификатор исключения, типа:
А>Что даёт спецификация исключения? Лично я предпочитаю ставить его везде, где это возможно, хотя бы затем, чтобы явно видеть, какие исключения может сгенерировать метод/функция. Что будет, если метод, помеченный как не генерирующий исключений, его всё таки сгенерирует? Как это сказывается на производительности? Или это несёт только информационную нагрузку для читающего код? Если нет, то хорошего/плохого я от этого получаю? Спасибо.
Как уже говорили, вызовёт unexpected если unexpected.
Между прочим VC6-никам об этом вообще заботиться не следует...