/Zc:throwingNew (Asumir que se inicia el operador new)
Cuando se especifica la opción /Zc:throwingNew, el compilador optimiza las llamadas a operator new
para omitir las comprobaciones de una devolución de puntero NULL. Esta opción indica al compilador que suponga que todas las implementaciones vinculadas de operator new
y los asignadores personalizados se ajustan al estándar de C++ y producen excepciones en caso de error de asignación. De forma predeterminada en Visual Studio, el compilador genera de forma pesimista comprobaciones nulas (/Zc:throwingNew-) para estas llamadas, ya que los usuarios pueden crear un vínculo con una implementación de operator new
que no produce excepciones o escribir rutinas de asignador personalizadas que devuelven punteros NULL.
Sintaxis
/Zc:throwingNew[-]
Comentarios
Desde ISO C++98, el estándar ha especificado que el operador new predeterminado produce std::bad_alloc
cuando se genera un error en la asignación de memoria. Las versiones de Visual C++ hasta Visual Studio 6.0 devolvían un puntero nulo en un error de asignación. A partir de Visual Studio 2002, operator new
se ajusta al estándar y produce excepciones en caso de error. Para admitir código que usa el estilo de asignación anterior, Visual Studio proporciona una implementación vinculable de operator new
en nothrownew.obj que devuelve un puntero nulo en caso de error. De forma predeterminada, el compilador también genera comprobaciones de valores NULL defensivas para evitar que estos asignadores de estilo anterior provoquen un bloqueo inmediato en caso de error. La opción /Zc:throwingNew indica al compilador que deje estas comprobaciones nulas, en el supuesto de que todos los asignadores de memoria vinculados se ajustan al estándar. Esto no se aplica a sobrecargas explícitas de operator new
que no producen excepciones, que se declaran mediante un parámetro adicional de tipo std::nothrow_t
y tienen una especificación noexcept
explícita.
Conceptualmente, para crear un objeto en el almacén libre, el compilador genera código para asignar su memoria y, luego, invocar su constructor para inicializar la memoria. Dado que el compilador de MSVC normalmente no puede saber si este código se vinculará a un asignador no conforme y que no produce excepciones, de forma predeterminada, también genera una comprobación nula antes de llamar al constructor. Esto evita una desreferencia de puntero nulo en la llamada al constructor si se genera un error en una asignación que no produce excepciones. En la mayoría de los casos, estas comprobaciones son innecesarias, ya que los asignadores operator new
predeterminados producen excepciones en lugar de devolver punteros NULL. Las comprobaciones también tienen efectos secundarios poco afortunados. Sobredimensionan el tamaño del código, inundan el predictor de rama e impiden otras optimizaciones útiles del compilador, como la desvirtualización o la propagación de constantes fuera del objeto inicializado. Las comprobaciones solo existen para admitir código que crea un vínculo con nothrownew.obj o tiene implementaciones personalizadas operator new
no conformes. Si no usa operator new
no conforme, se recomienda usar /Zc:throwingNew para optimizar el código.
La opción /Zc:throwingNew está desactivada de forma predeterminada y no se ve afectada por la opción /permissive-.
Si compila mediante la generación de código en tiempo de vínculo (LTCG), no es necesario especificar /Zc:throwingNew. Cuando el código se compila mediante LTCG, el compilador puede detectar si se usa la implementación operator new
conforme predeterminada. Si es así, el compilador deja las comprobaciones nulas automáticamente. El enlazador busca la marca /ThrowingNew para indicar si la implementación de operator new
es conforme. Puede especificar esta marca al enlazador mediante la inclusión de esta directiva en el origen de la implementación personalizada del operador new:
#pragma comment(linker, "/ThrowingNew")
Para obtener más información sobre los problemas de conformidad de Visual C++, vea Nonstandard Behavior.
Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio
Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para más información, vea Establecimiento del compilador de C++ y de propiedades de compilación en Visual Studio.
En el menú desplegable Configuración, elija Todas las configuraciones.
Seleccione la página de propiedades Propiedades de configuración>C/C++>Línea de comandos.
Modifique la propiedad Opciones adicionales para incluir /Zc:throwingNew o /Zc:throwingNew- y luego elija Aceptar.
Consulte también
Opciones del compilador de MSVC
Sintaxis de la línea de comandos del compilador MSVC
/Zc (Ajuste)
noexcept (C++)
Especificaciones de excepciones (throw) (C++)
terminate (excepción)