Почему «динамическое исключение» гарантия причина накладных расходов?

В C ++ 11 это не рекомендуется:

void foo() throw();

и заменен

void foo() noexcept;

В Эта статья объясняется, что причина этого (среди прочего, сводится к тому же) заключается в том, что

Спецификации исключений C ++ проверяются во время выполнения, а не во время компиляции, поэтому они не дают программисту гарантий того, что все исключения были обработаны.

Хотя для меня это имеет смысл, я не понимаю, почему throw() был динамически проверен в первую очередь, или почему noexcept не предоставляет исключений, кроме звонка std::terminate вместо обычного раскручивания стека (что на самом деле не является надежной гарантией IMO).

Не было бы возможно проверить, выбрасываются ли исключения во время компиляции и сбой компиляции, если это произойдет? На мой взгляд, есть в основном три случая:

void foo() noexcept
{
// 1. Trivial case
throw myexcept();

// 2. Try-catch case
//    Necessary to check whether myexcept is derived
//    from exception
try
{
throw myexcept();
}
catch(exception const & e)
{}

// 3. Nested function call
//    Recursion necessary
bar();
}

С шаблонами в C ++, создаваемыми для каждого типа, компиляция приложений в любом случае занимает бесконечно — так почему бы не изменить noexcept заставить компилятор проверить, генерируются ли исключения во время компиляции?

Единственная трудность, которую я вижу, состоит в том, что функция может выдавать или не выдавать в зависимости от состояний времени выполнения, но этой функции нельзя разрешать вызывать себя noexcept во всяком случае, на мой взгляд.

Я что-то упустил, или намеревался не увеличивать время компиляции дальше, или облегчить задачу разработчикам компиляторов?

5

Решение

Я думаю, что во многом это объясняется тем, что при определении спецификаций исключений авторы компиляторов сильно отставали от кривой мощности. Реализация C ++ 98 настолько сложна, что когда-либо один компилятор, который даже утверждал реализовать все его возможности. Любой другой компилятор исключил хотя бы одну важную функцию, которая была включена в стандарт. Наиболее честно признавалось, что они упустили значительно больше, чем это.

Вы также должны иметь в виду, что спецификации динамических исключений также были значительно сложнее, чем просто throw(), Это позволяет программисту указывать произвольный набор типов, которые могут быть выброшены. Хуже того, указав, что функция может бросить foo означает, что он также может выбросить что-нибудь из foo также.

Статическое применение спецификаций исключений могло бы быть выполнено, но это, несомненно, добавило бы немного дополнительной работы, и никто не был уверен, какую пользу (если таковая имеется) это даст. В этих обстоятельствах я думаю, что большинству было довольно легко подумать, что статическое принудительное применение было чем-то, что могло бы потребоваться позже, если, казалось, было достаточно использования, чтобы оправдать работу. Переход от принудительного исполнения во время выполнения к времени компиляции не потребует изменения существующего кода, а только существующих реализаций.

Другое дело, что я не уверен, что когда-либо сильный поддержка спецификаций исключений в любом случае. Я думаю, что было общее согласие по основной идее, но когда вы приступите к ней, вероятно, меньше о деталях.

Итог: было легко назначить только динамическое правоприменение и оставить статическое правоприменение на потом (если вообще было). Оказывается, статическое правоприменение, вероятно, в действительности не добавит столько положительного в любом случае, так что его обязательство, вероятно, в любом случае не достигло бы большого успеха.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]