/Zc:throwingNew (новые исключения оператора assume)

Если указан параметр /Zc:throwingNew , компилятор оптимизирует вызовы , operator new чтобы пропустить проверки возврата указателя NULL. Этот параметр указывает компилятору предположить, что все связанные реализации и пользовательских operator new распределителей соответствуют стандарту C++, и вызвать сбой выделения. По умолчанию в Visual Studio компилятор пессимистично создает проверки null (/Zc:throwingNew-) для этих вызовов, так как пользователи могут связываться с реализацией operator new без вызова или писать пользовательские подпрограммы распределителя, возвращающие пустые указатели.

Синтаксис

/Zc:throwingNew[-]

Комментарии

Начиная с ISO C++98, в стандарте указано, что оператор по умолчанию new создает std::bad_alloc исключение при сбое выделения памяти. Версии Visual C++ до Visual Studio 6.0 возвращали пустой указатель на сбой выделения. Начиная с Visual Studio 2002, operator new соответствует стандарту и вызывает сбой. Для поддержки кода, использующего старый стиль выделения, Visual Studio предоставляет связываемую реализацию operator new в nothrownew.obj, которая возвращает пустой указатель при сбое. По умолчанию компилятор также создает защитные проверки null, чтобы предотвратить немедленное завершение работы этих старых распределителей при сбое. Параметр /Zc:throwingNew указывает компилятору, что следует исключить эти проверки null при условии, что все связанные распределители памяти соответствуют стандарту. Это не относится к явным перегрузкам operator new , которые объявляются с помощью дополнительного параметра типа std::nothrow_t и имеют явную noexcept спецификацию.

По сути, чтобы создать объект в свободном хранилище, компилятор создает код для выделения памяти, а затем вызывает его конструктор для инициализации памяти. Поскольку компилятор MSVC обычно не может определить, будет ли этот код связан с несоответствующим, неизвежным распределителем, по умолчанию он также создает проверку значения NULL перед вызовом конструктора. Это предотвращает разыменовывание пустого указателя в вызове конструктора в случае сбоя выделения, не вызывающего исключение. В большинстве случаев эти проверки не нужны, так как распределители по умолчанию operator new выдают вместо возврата пустых указателей. Проверки также имеют неудачные побочные эффекты. Они раздувает размер кода, заполняют прогнозировщик ветвей и препятствуют другим полезным оптимизации компилятора, таким как девиртуализация или распространение констант из инициализированного объекта. Проверки существуют только для поддержки кода, который ссылается на nothrownew.obj или имеет пользовательские несоответствующие operator new реализации. Если вы не используете несоответствующие operator new, рекомендуется использовать /Zc:throwingNew для оптимизации кода.

Параметр /Zc:throwingNew отключен по умолчанию и не зависит от параметра /permissive- .

При компиляции с помощью создания кода времени компоновки (LTCG) указывать /Zc:throwingNew не нужно. При компиляции кода с помощью LTCG компилятор может определить, operator new используется ли соответствующая по умолчанию реализация. Если это так, компилятор автоматически опустит проверки null. Компоновщик ищет флаг /ThrowingNew , чтобы определить, соответствует ли реализация operator new . Этот флаг можно указать компоновщику, включив эту директиву в источник для новой реализации пользовательского оператора:

#pragma comment(linker, "/ThrowingNew")

Дополнительные сведения о вопросах соответствия в Visual C++ см. в статье Nonstandard Behavior.

Установка данного параметра компилятора в среде разработки Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. В раскрывающемся меню Конфигурация выберите Все конфигурации.

  3. Выберите страницу свойствC/C++>Command Lineсвойства> конфигурации.

  4. Измените свойство Дополнительные параметры , включив /Zc:throwingNew или /Zc:throwingNew-, а затем нажмите кнопку ОК.

См. также раздел

Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC
/Zc (соответствие)
noexcept (C++)
Спецификации исключений (throw) (C++)
terminate (исключение)