/Zc:throwingNew (Pressupor novos acionamentos de operador)

Quando a opção /Zc:throwingNew é especificada, o compilador otimiza as chamadas para operator new a fim de ignorar as verificações de um retorno de ponteiro nulo. Essa opção instrui o compilador a assumir que todas as implementações de operator new vinculadas e os alocadores personalizados estão em conformidade com o padrão do C++ e gerar uma falha de alocação. Por padrão, no Visual Studio, o compilador gera de modo pessimista verificações nulas (/Zc:throwingNew-) para essas chamadas, pois os usuários podem vincular com uma implementação no throw de operator new ou gravar rotinas personalizadas de alocador que retornam ponteiros nulos.

Sintaxe

/Zc:throwingNew[-]

Comentários

Desde o ISO C++98, o padrão especificou que o operador new padrão gera std::bad_alloc quando a alocação de memória falha. As versões do Visual C++ até o Visual Studio 6.0 retornavam um ponteiro nulo em uma falha de alocação. A partir do Visual Studio 2002, operator new está em conformidade com o padrão e gera em caso de falha. Para dar suporte ao código que usa o estilo de alocação mais antigo, o Visual Studio fornece uma implementação vinculável do operator new no nothrownew.obj que retorna um ponteiro nulo na ocorrência de falha. Por padrão, o compilador também gera verificações de nulidade defensivas para evitar que esses alocadores de estilo mais antigo causem uma falha imediata durante uma falha. A opção /Zc:throwingNew informa ao compilador para omitir essas verificações de nulidade na suposição de que todos os alocadores de memória vinculados estão em conformidade com o padrão. Isso não se aplica a sobrecargas explícitas no throw de operator new, que são declaradas usando um parâmetro adicional do tipo std::nothrow_t e têm uma especificação explícita noexcept.

Conceitualmente, para criar um objeto no repositório gratuito, o compilador gera um código para alocar a memória e, em seguida, invocar o construtor para inicializar a memória. Como o compilador do MSVC normalmente não pode informar se esse código será vinculado a um alocador no throw fora de conformidade, ele também vai gerar uma verificação de nulidade antes de chamar o construtor por padrão. Isso impede uma desreferência de ponteiro nulo na chamada do construtor caso uma alocação no throw falhe. Na maioria dos casos, essas verificações são desnecessárias, pois os alocadores padrão operator new geram em vez de retornar ponteiros nulos. As verificações também têm efeitos colaterais adversos. Elas sobrecarregam o tamanho do código, inundam o preditor de branch e inibem outras otimizações úteis do compilador, como desvirtualização ou propagação de const do objeto inicializado. As verificações existem apenas para dar suporte ao código que é vinculado ao nothrownew.obj ou tem implementações personalizadas sem conformidade de operator new. Se você não usar o operator new fora de conformidade, recomendamos que você use /Zc:throwingNew para otimizar seu código.

A opção /Zc:throwingNew fica desativada por padrão e não é afetada pela opção /permissive-.

Se você compilar usando a LTCG (Geração de Código Durante o Tempo de Vinculação), não precisará especificar /Zc:throwingNew. Quando o código é compilado usando LTCG, o compilador pode detectar se a implementação de operator new padrão e em conformidade é usada. Nesse caso, o compilador omite as verificações de nulidade automaticamente. O vinculador procura o sinalizador /ThrowingNew para saber se a implementação de operator new está em conformidade. Você pode especificar esse sinalizador para o vinculador incluindo essa diretiva na origem da implementação do operador new personalizado:

#pragma comment(linker, "/ThrowingNew")

Para obter mais informações sobre problemas de conformidade no Visual C++, confira Comportamento fora do padrão.

Para definir esta opção do compilador no ambiente de desenvolvimento do Visual Studio

  1. Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.

  2. No menu suspenso Configuração, escolha Todas as Configurações.

  3. Selecione a página de propriedades Propriedades de Configuração>C/C++>Linha de Comando.

  4. Modifique a propriedade Opções Adicionais para incluir /Zc:throwingNew ou /Zc:throwingNew- e escolha OK.

Confira também

Opções do compilador MSVC
Sintaxe da linha de comando do compilador MSVC
/Zc (conformidade)
noexcept (C++)
Especificações de exceção (lançar) (C++)
terminate (exceção)