Может ли 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]*[^;])|*)*}
это не проверено и может иметь некоторые ошибки, но хорошее место для начала