Что с "-fno-exception", что происходит с "new T"? - PullRequest
55 голосов
/ 18 мая 2011

Мне было интересно, будет ли new T по-прежнему выдавать bad_alloc, если я скомпилирую свою программу, используя опцию -fno-exceptions, чтобы отключить обработку исключений?

Или будет ли компилятор (GCC и clang поддерживать эту опцию)неявно преобразуйте использование new T в new (nothrow) T?

Ответы [ 4 ]

45 голосов
/ 06 февраля 2014

Как я понимаю, operator new определяется libstdc ++. Если вы сейчас скомпилируете свой собственный код с помощью -fno-exceptions, вы не сможете перехватить какие-либо исключения, но вы все равно будете ссылаться на обычную версию libstdc ++, которая выдает исключение.

Так что да, new T сгенерирует исключение, даже с -fno-exception.

Однако, если вы скомпилировали libstdc ++ и с -fno-exception, все станет иначе. Теперь new T не может выдать исключение, но, если я прочту руководство по libstdc ++ справа , вместо этого будет abort().

Похоже, что если вы хотите, чтобы ваш new T возвращал NULL в случае неудачи, единственный способ - явно указать nothrow ...

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

Я не могу дать однозначный ответ на все льготы, связанные с -fno-exception, только наблюдения на 32-битной машине linux, gcc 4.5.1 - bad_alloc генерируется с -fno-exceptions

* 1003 и без него*
9 голосов
/ 18 мая 2011

Это не окончательный ответ, но в Руководстве по GCC (см. Раздел «Обойтись без») есть следующее:

Перед подробным описанием поддержки библиотеки для -fno-exceptions,сначала краткая заметка о том, что потеряно при использовании этого флага: он прерывает исключения, пытаясь пройти через код, скомпилированный с -fno-exceptions, независимо от того, имеет ли этот код какие-либо конструкции try или catch.Если у вас может быть какой-то код, который выдает, вы не должны использовать -fno-exceptions.

. Как я это прочитал, вам, возможно, придется явно попросить, чтобы версия nothrow new была полностьюсейф.

0 голосов
/ 19 мая 2011

Во многих системах обработки исключений, если подпрограмма «foo» вызывает «bar», которая, в свою очередь, вызывает «moo», а «moo» выдает исключение, единственный способ, которым исключение может чисто вернуть его к «foo»если у "bar" есть код для обработки исключения.Даже если «bar» разрешит распространению исключения неперехваченным, ему, как правило, придется убедиться, что его локальные переменные должным образом уничтожены, прежде чем выполнению разрешат покинуть область действия.Это потребует добавления дополнительного кода в «bar»;в большинстве систем часть этого кода должна будет выполняться, даже если не выдано исключение.

BTW, на некоторых процессорах ARM, таких как Cortex M3 или, например, на Arm7, работающих в режиме ARM, если вызывающая сторона такжеБудучи запущенным в режиме ARM, можно разрешить исключения без каких-либо затрат времени выполнения, если «нормальный» возврат подпрограммы перейдет к LR + 4 (на четыре байта больше нормального адреса возврата) и получит исключительный выход к LR (который тогда будет 4-байтовой инструкцией ветвления).Такое поведение будет противоречить обычной практике ARM, и такой дизайн не будет хорошо переноситься на Cortex M0.

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