Я сам прошел эту же дилемму.
В основном, я пришел к выводу, что, принимая тот факт, что эти деструкторы бросают и просто живут с последствиями этого, обычно намного хуже, чем испытывать боль, из-за чего они не бросают.
Причина в том, что вы рискуете еще более неустойчивыми и непредсказуемыми состояниями, когда вы бросаете деструкторов.
В качестве примера я работал над проектом, когда, по разным причинам, некоторые разработчики использовали исключения для управления потоком в какой-то части проекта, и он работал отлично в течение многих лет. Позже кто-то заметил, что в другой части проекта иногда клиент не отправлял сетевые сообщения, которые он должен отправлять, поэтому они создали объект RAII, который отправил бы сообщения в свой деструктор. Иногда сетевое взаимодействие генерирует исключение, поэтому этот деструктор RAII будет бросать, но кто заботится правильно? У него нет памяти для очистки, поэтому это не утечка.
И это будет нормально работать в течение 99% времени, за исключением случаев, когда путь управления потоком исключений пересекается с сетью, что также порождает исключение. И тогда у вас есть два живых исключения, которые разматываются сразу, так что «bang you're dead», в бессмертных словах C++ FAQ.
Честно говоря, я бы предпочел, чтобы программа немедленно прекратилась, когда деструктор выбрасывает, поэтому мы можем поговорить с тем, кто написал деструктор бросания, чем пытаться поддерживать программу с намеренно метательными деструкторами, и это консенсус комитета/сообщество кажется. Таким образом, они сделали это изменение, чтобы помочь вам утверждать, что ваши деструкторы хороши и не бросают. Это может быть много работы, если у вас есть устаревшая кодовая база, но если вы хотите продолжать ее развивать и поддерживать, по крайней мере, на стандарте C++ 11, вам, скорее всего, лучше сделать работу по очистке до деструкторов.
Bottom Line:
Вы правы, вы не можете надеяться, чтобы гарантировать, что вы найдете все возможные случаи метания деструктора. Таким образом, вероятно, будут некоторые сценарии, где, когда ваш код компилируется на C++ 11, он будет разбиваться в случаях, когда он не будет соответствовать стандарту C++ 98. Но в целом, очистка деструкторов и работа на C++ 11, вероятно, будет намного более стабильной, чем просто с деструкторами бросания по старому стандарту.
Интересно, что головная версия gcc предоставляет предупреждение для этого через '-Wterminate'. Я не вижу аналогичного варианта для clang. –
Как я всегда говорил, спецификация исключений на языке С ++ - это шутка. Извините, нет конструктивного asnwer, но я разделяю вашу боль. – SergeyA
@ShafikYaghmour Это интересно, но мой GCC 5.2.0 не распознает этот вариант. У вас есть ссылка на него? – 5gon12eder