Может ли g++ проверить спецификаторы броска?

Два вопроса по этому поводу:

  • Есть ли способ заставить g++ игнорировать throw спецификаторы?
    (например, насколько я помню, Visual Studio игнорирует спецификаторы броска, отличные от throw())

  • Можно ли заставить g++ проверить правильность спецификаторов броска - я имею в виду проверить (и это может быть сделано однопроходными компиляторами), если функции со спецификаторами броска вызывают функции, которые могут выбрасывать, просто наблюдая за их спецификаторами броска и следя за выполнением throw за исключением, что будет нарушать спецификаторы? (Примечание: это не должно наблюдать за функциями без спецификаторов броска, потому что это может вызвать массу предупреждений)


РЕДАКТИРОВАТЬ: я добавлю несколько примеров для моего второго вопроса.

Предположим, у нас есть:

// sorry for the coding style here, but I don't want it to be unnecessary long
class A { /* .. */ };
class B : public A { /* .. */ };
class C { /* .. */ };
void no_throw_spec() { /* .. */ }
void no_throw_at_all() throw() { /* .. */ }
void throws_A() throw( A ) { /* .. */ }

// this is fine, don't do anything
void f() 
{ no_throw_spec(); no_throw_at_all(); throws_A(); }

void g() throw()
{ 
    no_throw_spec(); no_throw_at_all(); // OK
    throws_A();  // warning here - throws_A() may throw A, but g() has throw()!
}

void h() throw( A )
{
    no_throw_spec(); no_throw_at_all(); throws_A(); // OK
    if( /* .. */ ) 
        throw B(); // OK, B inherits A, it's OK
    /* .. */
    throw C();    // C does not inherit A, so WARNING!
}

2 ответа

Решение
  • у gcc есть опция -fno-enforce-eh-specsпосмотрите документацию и убедитесь, что она делает то, что вы хотите.

  • Я не помню никакого способа статической проверки спецификаций исключений с помощью gcc.

Обратите внимание, что (динамические) исключения исключены в C++0X, которые добавляют noexcept спецификация исключений заменяет пустой случай спецификации исключений (он также проверяется динамически и содержит положения, помогающие использовать его в шаблонах).

Да, вы можете заставить g++ игнорировать throw:

#define throw(x)

В остальном вам нужно изменить код компилятора или создать свой собственный скрипт / программу в процессе сборки, которая будет проверять эти вещи, это можно легко сделать с помощью regexp.

Редактировать:

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

class ([^ ]*) : ([^ ]*)

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

([^\(\s]*)[\s]*([^\)])[\s]*(throw[\s]*\([^\)]*\)){((throw[\s]*[^;])|*)*}

это не проверено и может иметь некоторые ошибки, но хорошее место для начала

Другие вопросы по тегам