Вопрос по visual-c++, c++, exception – Почему исключения в C ++ не проверяются компилятором?

40

C ++ предоставляет синтаксис для проверенных исключений, например:

<code>void G() throw(Exception);
void f() throw();
</code>

Однако компилятор Visual C ++ их не проверяет; флаг броска просто игнорируется. На мой взгляд, это делает функцию исключения непригодной. Итак, мой вопрос:is there a way to make the compiler check whether exceptions are correctly caught/rethrown? Например, плагин Visual C ++ или другой компилятор C ++.

PS. Я хочу, чтобы компилятор проверил, правильно ли перехватываются исключения, в противном случае вы попадаете в ситуацию, в которой вам нужно ставить перед собой каждый вызов функции,even if they explicitly state they won't throw anything.

Update: компилятор Visual C ++ выдает предупреждение при добавлении функции, помеченной throw (). Это здорово, но, к сожалению, предупреждение не появляется, когда вы вызываете подпрограмму, которая может выдать. Например:

<code>void f() throw(int) { throw int(13); }
void h() throw() { g(); } //no warning here!
</code>
Я никогда не слышал о проверенных исключениях в C ++, но сейчас я делаю о спецификации исключений и о том, что Visual C ++ не заботится о них, посмотрим здесь:msdn.microsoft.com/en-us/library/wfa0edys.aspx Skurmedel
Visual C ++ не совсем игнорирует это ... добавление throw () в конец функции говорит Visual C ++, что она может предполагать, что функция не выбрасывает, например, в целях оптимизации, и если функция действительно выдает, тогда может произойти все что угодно. Стандарт гласит, что если функция помечена, как throw (), выходит из-за исключения, тогда std :: surprise (), который обычно выбрасывает std :: bad_exception Это очень отличается от «всего, что может случиться». Doug
Если спецификации исключений являются подсказками для компиляторов, а не требованиями что-либо делать, они потенциально могут быть полезны. Стандартное поведение, на мой взгляд, бесполезно. David Thornley

Ваш Ответ

6   ответов
15

http://www.gotw.ca/publications/mill22.htm

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

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Dimitri C.
there is no way to get the compiler to check that every type thrown is caught somewhere higher in the codeError: User Rate Limit Exceeded
38

так это то, что Java проверила исключения, и программисты на Java тоже их ненавидят.

Спецификации исключений в C ++ бесполезны по 3 причинам:

1. C++ exception specifications inhibit optimization.

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

2. C++ exception specifications are not compiler-enforced

Что касается вашего компилятора, то синтаксически правильно следующее:

void AStupidFunction() throw()
{
    throw 42;
}

Что еще хуже, ничего полезного не произойдет, если вы нарушите спецификацию исключений. Ваша программа просто заканчивается!

3. C++ exception specifications are part of a function's signature.

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

struct A
{
    virtual int value() const throw() {return 10;}
}

struct B : public A
{
    virtual int value() const {return functionThatCanThrow();} // ERROR!
}

Спецификации исключений дают вам эти проблемы, и выгода от их использования минимальна. Напротив, если вы вообще избегаете спецификаций исключений, кодирование становится проще, и вы избегаете этого.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
30

Не обязательно, чтобы не было выброшено никаких других исключений, а только то, что глобальная функцияunexpected() будет вызван (который может быть установлен)

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
9

extern void f() throw (class Mystery);
void g() throw() { 
    f() ; 
}

... тебе нужноstatic analysis, Да, компилятор выполняет много статического анализа, но поскольку стандартом является «повышение std :: непредсказуемо, если бросок не соответствует», & quot; и совершенно законно написать подпрограмму, которая выбрасывает объект, который не соответствует спецификатору, разработчики компилятора не предупреждают и не замечают.

Инструменты статического анализа, которые утверждают, что предоставляют услугу предупреждения, включают программное обеспечение Gimpel.lint for C++ ...

1560 Uncaught exception 'Name' not on throw-list for function 'Symbol'

и, согласноэтот ответ на предыдущий вопрос,QA C ++.

0

но вы действительно уверены, что компилятор игнорирует спецификацию throw ()?

Эта страница MSDN предполагает, что Microsoft знает о throw () и ожидает, что их компилятор будет обрабатывать его правильно. Ну, почти, см. Примечание о том, как они отступают от стандарта ANSI / ISO в некоторых деталях.

Edit: Однако на практике я согласен с Патриком: спецификации исключений в основном бесполезны.

8

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

Похожие вопросы