Программисты C ++ не ищут спецификации исключений. Они ищут гарантии исключений.
Предположим, что фрагмент кода выдал исключение. Какие предположения может сделать программист, которые все еще будут действительны? Что написано в коде, что гарантирует код после исключения?
Или это возможно, что определенный кусок кода может гарантировать, что никогда не выбросит (то есть, ничего, кроме процесса ОС будет прекращено)?
Слово «откат» часто встречается в дискуссиях об исключениях. Возможность возврата к допустимому состоянию (которое явно задокументировано) является примером гарантии исключения. Если нет гарантии исключения, программа должна завершиться на месте, потому что даже не гарантируется, что любой код, который она выполнит после этого, будет работать как задумано - скажем, если память была повреждена, любая дальнейшая операция является технически неопределенным поведением.
Различные методы программирования на C ++ обеспечивают гарантии исключений. RAII (управление ресурсами на основе области действия) предоставляет механизм для выполнения кода очистки и обеспечивает высвобождение ресурсов как в обычных, так и в исключительных случаях. Создание копии данных перед выполнением изменений на объектах позволяет восстановить состояние этого объекта в случае сбоя операции. И так далее.
Ответы на этот вопрос StackOverflow дают представление о том, как долго программисты на C ++ разбираются во всех возможных режимах сбоев, которые могут случиться с их кодом, и пытаются защитить достоверность состояния программы, несмотря на сбои. Строковый анализ кода C ++ становится привычкой.
При разработке на C ++ (для производственного использования) никто не может позволить себе замаскировать детали. Кроме того, двоичный двоичный объект (не с открытым исходным кодом) - проклятие программистов на C ++. Если мне нужно вызвать какой-нибудь двоичный двоичный объект, и этот двоичный объект не работает, то обратный инжиниринг - это то, что программист C ++ сделает дальше.
Ссылка: http://en.cppreference.com/w/cpp/language/exceptions#Exception_safety - см. В разделе «Безопасность исключений».
В C ++ не удалось реализовать спецификации исключений. Более поздний анализ на других языках говорит, что спецификации исключений просто не практичны.
Почему это неудачная попытка: для строгого соблюдения она должна быть частью системы типов. Но это не так. Компилятор не проверяет спецификацию исключений.
Почему C ++ выбрал это, и почему опыт из других языков (Java) доказывает, что спецификация исключений является спорным: Как один изменить реализацию функции (например, он должен сделать вызов другой функции, которая может бросить новый вид исключение), строгое соблюдение спецификации исключений означает, что вы также должны обновить эту спецификацию. Это распространяется - вам может понадобиться обновить спецификации исключений для десятков или сотен функций, что является простым изменением. Ситуация ухудшается для абстрактных базовых классов (эквивалент интерфейсов C ++). Если спецификация исключений применяется к интерфейсам, реализациям интерфейсов не разрешается вызывать функции, которые генерируют различные типы исключений.
Ссылка: http://www.gotw.ca/publications/mill22.htm
Начиная с C ++ 17, этот [[nodiscard]]
атрибут можно использовать для возвращаемых значений функции (см .: https://stackoverflow.com/questions/39327028/can-ac-function-be-declared-such-that-the-return-value не может быть проигнорировано ).
Так что, если я сделаю изменение кода, и это вводит новый тип условия отказа (то есть новый тип исключения), будет ли это критическое изменение? Должен ли он был заставить вызывающего абонента обновить код или хотя бы получить предупреждение об изменении?
Если вы принимаете аргументы, что программисты на C ++ ищут гарантии исключений вместо спецификаций исключений, тогда ответ таков: если условие сбоя нового типа не нарушает какие-либо исключения, гарантирует код, обещанный ранее, это не является критическим изменением.