Может ли g ++ проверить спецификаторы броска? - PullRequest
4 голосов
/ 18 мая 2011

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

  • Есть ли способ заставить 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 ]

3 голосов
/ 18 мая 2011
  • gcc имеет опцию -fno-enforce-eh-specs, посмотрите документацию и убедитесь, что она делает то, что вам нужно.

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

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

2 голосов
/ 18 мая 2011

Да, вы можете заставить g ++ игнорировать бросок с помощью:

#define throw(x)

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

Edit:

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

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

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

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

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

...