Есть ли какой-либо способ, не доставляющий атрибут для каждого прототипа функции, чтобы gcc знал, что C-функции никогда не могут распространять исключения, т.е. что все функции, объявленные внутри extern "C"
, должны быть __attribute__((nothrow))
? Идеал был бы в командной строке -f
.
Есть ли опция gcc, чтобы все внешние функции "C" не могли распространять исключения?
Ответ 1
Вы всегда можете использовать -fno-exceptions
, который гарантирует, что компилятор С++ не генерирует код распространения исключений.
Ответ 2
Боковое примечание:
Вы уверены, что компилятор "все эти функции никогда не бросать" - это именно то, что вы хотите?
Это не обязательно, так что функции extern "C" ...
не могут распространять/запускать исключения. Возьмите пример:
class Foo {
public:
class Away {};
static void throwaway(void) { throw Away(); }
}
extern "C" {
void wrap_a_call(void (*wrapped)(void)) { wrapped(); }
}
int main(int argc, char **argv)
{
wrap_a_call(Foo::throwaway);
return 0;
}
При компиляции и запуске создается функция C-linkage wrap_a_call()
, которая при вызове, как указано выше, с радостью вызовет исключение:
$ ./test
terminate called after throwing an instance of 'Foo::Away'
Abort(coredump)
т.е. может быть "утечка исключений" с помощью extern "C"
(путем вызова указателей на функции), и только потому, что вы используете/вызываете extern "C"
функции в определенном месте на С++, не гарантирует, что при вызове этих исключений не могут быть исключены.
Ответ 3
Когда возникает исключение, создается прерывание, которое разворачивает стек и переопределяет существующий стек. Он поднимается до точки, где используется try/except синтаксис. Это означает, что у вас нет накладных расходов, если вы не используете исключения. Только накладные расходы в памяти/времени находятся в блоках try/catch и разворачивании стека в throw().
Если ваши c-функции не генерируют исключения, ваши служебные данные будут находиться только в космосе, когда вы вызываете try/catch на вашем С++, но одинаковы для любого количества исключений. (и небольшой промежуток времени при инициализации этого небольшого пробела).
Ответ 4
GCC 4.5, похоже, автоматически оптимизирует их для меня. Действительно, эта строка появляется в списке изменений на http://gcc.gnu.org/gcc-4.5/changes.html:
- Теперь GCC оптимизирует код обработки исключений. В частности, оптимизированы области очистки, которые оказались неэффективными.