Я только что прочитал, что в стандартной редакции C ++ 11 спецификации исключений устарели. Раньше я думал, что указание того, что могут выполнять ваши функции, — хорошая практика, но, видимо, это не так.
После прочтения Хорошо цитируемая статья Херба Заикания, Я не могу не задаться вопросом: почему спецификации исключений реализованы так, как они есть, и почему комитет решил отказаться от них, вместо того, чтобы проверять их во время компиляции? Почему компилятор даже допускает создание исключения, которое не отображается в определении функции? Для меня все это звучит как сказать «Вы, вероятно, не должны указывать тип возвращаемого значения вашей функции, потому что когда вы указываете int f()
, но return 3.5;
внутри него ваша программа, скорее всего, потерпит крах. «(т.е. где находится концептуальный отличие от строгой печати?)
(За отсутствием поддержки спецификации исключений в typedef
s, учитывая, что синтаксис шаблона, вероятно, завершен по Тьюрингу, реализовать это достаточно просто.)
Первоначальная причина заключалась в том, что было сочтено невозможным
надежная проверка с учетом существующего кода и факта
что никакой спецификатор не означает, что что-либо может бросить. Который означает, что
если статическая проверка была в силе, следующий код не будет
компиляции:
double
safeSquareRoot( double d ) throw()
{
return d > 0.0 ? sqrt( d ) : 0.0;
}
Кроме того, целью исключений является сообщение об ошибках в течение
большое расстояние, а это значит, что промежуточные функции
не должен знать, какие функции они могут вызывать.
Требование спецификаторов исключений на них сломалось бы
инкапсуляция.
Единственный реальный случай, когда функция должна знать о
исключения, которые могут возникнуть, это знать, что исключения не могут
происходят. В частности, невозможно написать потокобезопасный код
если вы не можете быть уверены, что некоторые функции никогда не будут
бросить. Даже здесь статическая проверка не приемлема для
причины, объясненные выше, поэтому спецификация исключения
разработан, чтобы работать больше как утверждение, что вы не можете
дезактивировать: когда пишешь throw()
, вы получите более или менее
эквивалент ошибки подтверждения, если функция завершена
исключением.
Ситуация в Java несколько иная. В Java
нет никаких реальных параметров, что означает, что если вы не можете
используйте коды возврата, если функция также имеет возвращаемое значение.
Результатом является то, что исключения используются во многих случаях, когда
код возврата будет предпочтительнее. И эти, вы должны
знать о, и справиться немедленно. Для вещей, которые должны
действительно быть исключениями, Java имеет java.lang.RuntimeException
(который не проверен, статически или иначе). И это не имеет
способ сказать, что функция никогда не может генерировать исключение; Это
также использует непроверенные исключения (называемые Error
в случаях, когда
прерывание программы было бы более уместным.
Если функция f() throw(int)
называется функцией g() throw(int, double)
что случилось бы?
Проверка во время компиляции не позволит вашей функции вызывать любую другую функцию с менее строгим спецификатором throw, что будет огромной болью.