Поделиться через


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

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

Синтаксис

/Zc:throwingNew[-]

Замечания

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

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

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

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

#pragma comment(linker, "/ThrowingNew")

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

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

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

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

  3. Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.

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

См. также

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