Есть ли опция gcc, позволяющая предположить, что все внешние функции "C" не могут распространять исключения? - PullRequest
27 голосов
/ 14 января 2011

Есть ли способ, кроме добавления атрибута к каждому прототипу функции, позволить gcc знать, что функции C никогда не могут распространять исключения, то есть что все функции, объявленные внутри extern "C", должны быть __attribute__((nothrow))?Идеальным вариантом будет опция командной строки в стиле -f.

Ответы [ 4 ]

3 голосов
/ 15 января 2011

Вы всегда можете использовать -fno-exceptions, чтобы компилятор c ++ не генерировал код распространения исключений.

2 голосов
/ 23 января 2012

Примечание:
Вы уверены, что сказать компилятору "все эти функции никогда не выдают" - это именно то, что вам нужно?

Это не обязательно, так что 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" в определенном месте в C ++, не гарантирует , исключение не можетбыть брошенным при вызове тех.

0 голосов
/ 16 февраля 2011

GCC 4.5, кажется, оптимизирует их для меня автоматически.Действительно, эта строка появляется в списке изменений на http://gcc.gnu.org/gcc-4.5/changes.html:

  • Теперь GCC оптимизирует код обработки исключений.В частности, оптимизируются области очистки, которые, как доказано, не оказывают никакого влияния.
0 голосов
/ 12 февраля 2011

При возникновении исключения генерируется прерывание, которое разворачивает стек и переопределяет существующий стек.Доходит до точки, где используется синтаксис try / кроме.Это означает, что у вас нет никаких накладных расходов, если вы не используете исключения.Только издержки в памяти / времени находятся в блоках try / catch, а стек разворачивается при throw ().

Если ваши функции c не генерируют исключения, ваши издержки будут только в пространстве, когда вы будете вызывать try / catch в вашем C ++, но одинаковы для любого числа исключений.(и небольшие накладные расходы на инициализацию этой небольшой постоянной пространства).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...