> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Recomendaciones de modificadores del compilador y el enlazador de Visual C++

> Recomendaciones de modificadores del compilador y el enlazador de Visual C++

En este tema se describen los distintos modificadores del compilador y el enlazador de Visual C++ que se recomiendan para Microsoft Game Development Kit (GDK) en el desarrollo para XBOX.

> Para clang/LLVM para Windows, se admiten los mismos modificadores a través del front-end clang-cl "similar a MSVC". A continuación, se indican algunos modificadores específicos del conjunto de herramientas de clang.

## Estándar del lenguaje C++ (`/std`)

Visual C++ usa de forma predeterminada el modo de conformidad con C++14. Para habilitar el modo de conformidad con C++17, use `/std:c++17`. Las API de Microsoft Game Development Kit (GDK) en XBOX requieren C++11 o posterior, y el uso de C++14 o posterior es totalmente compatible para el desarrollo de títulos.

> [!NOTE]
>
> `/std:c++latest` habilita la conformidad con el borrador de C++20 para Visual Studio 2017 y Visual Studio 2019. Dado que el comportamiento de `/std:c++latest` sigue cambiando con las actualizaciones de servicio de Visual C++, debe usarse con cierta precaución.

> VS 2019 (16.11) y VS 2022 admiten el modificador `/std:c++20`. Consulte [esta entrada de blog](https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/).

> A partir de VS 2019 (16.8), el compilador de Visual C++ admite `/std:c11` y `/std::c17`. Sin embargo, GameRuntime y muchos otros encabezados del GDK requieren C++11 o posterior.

Para obtener más información, consulte lo siguiente:

* [/std (Specify Language Standard Version)](https://learn.microsoft.com/cpp/build/reference/std-specify-language-standard-version) (Microsoft Docs)
* [Standards version switches in the compiler](https://devblogs.microsoft.com/cppblog/standards-version-switches-in-the-compiler/) (C++ Team Blog)
* [C11 and C17 Standard Support Arriving in MSVC](https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/) (C++ Team Blog)

## Use `/O1 /Oi` para la optimización general y `/O2` para los módulos "críticos"

Para la CPU de ejecución fuera de orden de XBOX One y XBOX Series X/S, conseguir que un segmento de código quepa en la caché de instrucciones suele ser más importante que obtener la versión absolutamente más rápida del código, por lo que se prefiere *optimizar para espacio*. Reserve el uso de *optimizar para velocidad* solo para módulos o funciones específicos. La generación de intrínsecos compensa el código adicional en los juegos porque mejora el rendimiento de punto flotante. También puede habilitar *optimizar para velocidad* en una función o un conjunto de funciones específicos rodeándolos con `#pragma optimize("t", on)` / `#pragma optimize("", on )`. Recuerde que *optimizar para velocidad* (`/O2` o `/Ox`) puede provocar un aumento drástico del tamaño del programa debido al desenrollado agresivo de bucles.

> [!NOTE]
>
> Las optimizaciones del vectorizador automático de instrucción única, datos múltiples (SIMD) solo se habilitan con `/O2` o `/Ox`. La optimización guiada por perfiles (PGO) puede tomar mejores decisiones sobre dónde aplicar exactamente *optimizar para velocidad* frente a *optimizar para espacio*.
>
> Por motivos históricos, es importante tener en cuenta que `/Ox` es casi igual que `O2`, pero le faltan tanto `/GF` (eliminar cadenas duplicadas) como `/Gy` (habilitar vinculación en el nivel de función). Por lo tanto, en general debe preferir usar `/O2` en lugar de `/Ox`. Si usa `/Ox`, asegúrese de habilitar explícitamente al menos `/Gy`, que es importante para habilitar la optimización del enlazador.

## Modificador del compilador `/fp:fast`

La marca `/fp`, introducida con Visual Studio 2005, controla los distintos modelos de punto flotante que usa el compilador (fast, precise, strict, except). El modelo de punto flotante rápido usa una serie de optimizaciones que no forman parte de las reglas básicas de "C". El modelo de punto flotante preciso deshabilita estas optimizaciones adicionales y es el predeterminado. Se recomienda usar `/fp:fast` para los juegos.

Para obtener más información, consulte lo siguiente:

* [/fp (Specify floating-point behavior)](https://learn.microsoft.com/cpp/build/reference/fp-specify-floating-point-behavior) (Microsoft Docs)
* [Do You Prefer Fast or Precise? ](https://devblogs.microsoft.com/cppblog/do-you-prefer-fast-or-precise/) (C++ Team Blog)

Consulte también estas marcas adicionales relacionadas con el punto flotante, nuevas en VS 2022:

* [/fpcvt](https://devblogs.microsoft.com/cppblog/microsoft-visual-studio-2022-and-floating-point-to-integer-conversions/)
* [/fpcontract](https://devblogs.microsoft.com/cppblog/the-fpcontract-flag-and-changes-to-fp-modes-in-vs2022/)

## Modificador del compilador `/arch`

El valor predeterminado implícito para las plataformas nativas x64 es `/arch:SSE2`. Para las consolas XBOX One (CPU AMD Jaguar), debe usar `/arch:AVX`. Para XBOX Series X/S (CPU AMD Hercules), se recomienda usar `/arch:AVX2`.

La principal ventaja de usar `/arch:AVX` o `/arch:AVX2` es que hace que el compilador genere versiones con prefijo VEX de las instrucciones SSE que usan una codificación no destructiva de 3 operandos en lugar de la codificación estándar de 2 operandos, en la que uno de los operandos de origen se sobrescribe con el resultado. Esto afecta tanto al punto flotante escalar del código nativo x64 que usa instrucciones SSE como al uso explícito de intrínsecos SSE. Esto ayuda a reducir la presión de programación de registros y puede eliminar algunas instrucciones `movaps`.

Para obtener más información, consulte lo siguiente:

* [/arch (x64)](https://learn.microsoft.com/cpp/build/reference/arch-x64) (Microsoft Docs)
* [AVX2 floating point improvements in Visual Studio 2019 version 16.5](https://devblogs.microsoft.com/cppblog/avx2-floating-point-improvements-in-visual-studio-2019-version-16-5/) (C++ Team Blog)

Para XBOX Series X|S con Visual Studio 2019 (16.3) o posterior, también debe usar `/d2vzeroupper` para optimizar según el comportamiento preferido de la CPU AMD Hercules en el uso de la instrucción `vzeroupper`. Para la optimización de todo el programa (`/LTCG`), el equivalente necesario del enlazador es `/d2:-vzeroupper`. Este es el comportamiento predeterminado del compilador de VS 2022.

Para XBOX One con Visual Studio 2022, también debe usar `/d2vzeroupper-` para optimizar según el comportamiento preferido de la CPU AMD Jaguar en el uso de la instrucción `vzeroupper`. Para la optimización de todo el programa (`/LTCG`), el equivalente necesario del enlazador es `/d2:-vzeroupper-`. Este es el comportamiento predeterminado del compilador de VS 2019.

> Para clang/LLVM, use `-march=btver2` para XBOX One (CPU AMD Jaguar) y `-march=znver2` para XBOX Series X/S (CPU AMD Hercules).

> Para el desarrollo en PC, puede contar con que todas las CPU nativas x64 admiten SSE y SSE2, ya que forman parte de la definición de la arquitectura. También puede exigir SSE3 con seguridad, ya que es compatible con todas las CPU modernas de Intel compatibles con Windows 10 o Windows 11. Asegúrese de realizar comprobaciones de compatibilidad de CPU en tiempo de ejecución para cualquier elemento que use más allá de SSE2 en PC, como AVX o AVX2.

## Modificador del compilador `/favor`

El modificador `/favor` controla las opciones de optimización del compilador x64 para procesadores AMD64 frente a Intel 64. Para el desarrollo para XBOX, use `/favor:AMD64`.

## Modelo de control de excepciones (`/EHsc`)

En el código nativo x64, el control de excepciones no tiene ningún efecto directo en el código del epílogo ni del prólogo de las funciones. Mientras que Windows x86 usaba un esquema basado en la pila que implicaba código adicional insertado en los módulos, la generación de código nativo x64 usa un esquema basado en tablas para garantizar que la pila se pueda desenredar correctamente durante el procesamiento de excepciones. El esquema basado en tablas que usa el código nativo x64 también tiene la ventaja de ser más seguro, ya que no está expuesto a ataques de saturación del búfer de pila. Este diseño tiene una serie de implicaciones.

* El control de excepciones no afecta al número de instrucciones del código generado. Mientras que los esquemas basados en la pila, como los usados en Windows x86, pueden provocar una penalización de código del 5 al 10 por ciento, el control de excepciones nativo de x64 solo genera datos basados en tablas asociados al ejecutable y no más instrucciones. Incluso deshabilitar explícitamente el control de excepciones para el código nativo x64, algo que no se recomienda, solo ahorra una pequeña cantidad de datos auxiliares para el control de C++ y no deshabilita la generación de datos de desenredo de la pila.

* Los bloques try/catch son económicos de usar. Un bloque try/catch en el esquema basado en la pila agrega código adicional para el seguimiento. En x64, solo agrega algunas entradas más en la tabla de desenredo.

* El procesamiento de excepciones (es decir, el lanzamiento real de una excepción) requiere algunas búsquedas adicionales en tablas. La contrapartida es que, aunque los esquemas basados en la pila pueden lanzar excepciones más rápidamente, lo hacen con una penalización en todas las rutas de código. El esquema basado en tablas es más lento al "lanzar", pero no afecta a otras rutas de código. Dado que las excepciones no deben usarse como control de flujo normal y, de hecho, solo deben desencadenarse en circunstancias excepcionales, este costo de rendimiento adicional del procesamiento es insignificante en comparación con el rendimiento general de la aplicación.

Las API de Microsoft Game Development Kit (GDK) en XBOX usan códigos de error o `HRESULT` en lugar del control de excepciones para devolver resultados de error, por lo que el nivel de adopción del control de excepciones de C++ en el código base de un título depende totalmente de usted. Las excepciones no deben usarse para el control de flujo, por lo que, en general, su mejor uso es en escenarios de "error rápido", lo que puede simplificar la depuración y la codificación. Gran parte de la biblioteca estándar de C++ supone que el control de excepciones está habilitado para un control de errores adecuado.

No se recomienda deshabilitar explícitamente el control de excepciones, ya que afecta negativamente al análisis posterior a un bloqueo y no mejora la generación de código. No se recomienda el uso de `/EHa`, ya que puede inhibir el optimizador.

> [!NOTE]
>
> El operador `new` siempre lanza una excepción de C++ cuando se produce un error en una asignación. Si desea usar una versión de `new` que no lance excepciones, debe usar `new (std::nothrow)`. Para obtener más información, consulte [std::nothrow](https://en.cppreference.com/w/cpp/memory/new/nothrow) (cppreference.com).

C++ proporciona numerosos mecanismos para escribir código "seguro frente a excepciones" que funciona bien tanto con como sin el uso explícito del control de excepciones. Por ejemplo, `std::unique_ptr`, `std::shared_ptr` y `std::lock_guard`. El uso de un puntero inteligente COM como [Microsoft::WRL::ComPtr](https://learn.microsoft.com/cpp/cppcx/wrl/comptr-class) para controlar automáticamente el recuento de referencias de COM es "seguro frente a excepciones" y menos propenso a errores. En general, debe preferir el uso de patrones de codificación de adquisición de recursos es inicialización ([RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)).

> [!NOTE]
>
> De forma predeterminada, el código nativo x64 compilado con VS 2019 usa una implementación mejorada del controlador de excepciones (` __CxxFrameHandler4`, `__GSHandlerCheck_EH4`). Por lo tanto, las bibliotecas estáticas compiladas con VS 2019 no son compatibles con el entorno de ejecución de C/C++ de VS 2017. Las bibliotecas estáticas compiladas con VS 2017 son compatibles con VS 2019.

Para obtener más información, consulte lo siguiente:

* [/EH (Exception handling model)](https://learn.microsoft.com/cpp/build/reference/eh-exception-handling-model) (Microsoft Docs)
* [x64 exception handling](https://learn.microsoft.com/cpp/build/exception-handling-x64) (Microsoft Docs)
* [Making C++ Exception Handling Smaller On x64](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) (C++ Team Blog)

## Biblioteca en tiempo de ejecución (`/MD`, `/MDd`)

La opción recomendada es usar la versión *DLL multiproceso* del entorno de ejecución de Visual C/C++. Esto minimiza el exceso de código, evita posibles problemas con las interacciones entre DLL, simplifica el mantenimiento y es la opción recomendada para todas las plataformas de Microsoft.

Para Microsoft Game Development Kit (GDK) en XBOX, esto significa vincular con `ucrt.lib` o `ucrtd.lib`.

> [!NOTE]
>
> Técnicamente, puede usar la vinculación estática de CRT mediante `/MT`, `/MTd` con `libucrt.lib` o `libucrtd.lib`. El GDK no contiene bibliotecas de extensión compatibles con la CRT estática, por lo que la compatibilidad con este escenario es limitada.

## Convención de llamada (`/Gd`, `/Gv`)

La generación de código nativo para x64 usa una convención de llamada `__fastcall` sencilla y estándar que puede pasar los primeros cuatro parámetros en registros.

* Si el primer parámetro es un entero o un equivalente de puntero, se pasa en RCX. Si es `float` o `double`, se pasa en XMM0L. De lo contrario, se pasa por la pila.
* Si el segundo parámetro es un entero o un equivalente de puntero, se pasa en RDX. Si es `float` o `double`, se pasa en XMM1L. De lo contrario, se pasa por la pila.
* Si el tercer parámetro es un entero o un equivalente de puntero, se pasa en R8. Si es `float` o `double`, se pasa en XMM2L. De lo contrario, se pasa por la pila.
* Si el cuarto parámetro es un entero o un equivalente de puntero, se pasa en R9. Si es `float` o `double`, se pasa en XMM3L. De lo contrario, se pasa por la pila.
* Todos los demás parámetros se pasan por la pila.
* Un valor devuelto que cabe en 64 bits se devuelve en RAX. XMM0 se usa para devolver valores `float`, `double`, `__m128`, `__m128i` y `__m128d`. De lo contrario, el autor de la llamada pasa un puntero a la memoria como argumento 0 en RCX, y RAX debe devolverse con el mismo puntero.

Estos puntos implican que las firmas de función más cortas ofrecen mejor rendimiento y que pasar punteros (o referencias) a objetos es más rápido que pasarlos por valor. La convención de llamada pasará automáticamente por referencia los objetos de más de 8 bytes.

Los valores SIMD nunca se pasan en registros con el esquema `__fastcall`.

> [!NOTE]
>
> `__cdecl`, `__stdcall` y `__thiscall` son todos alias de `__fastcall` para el código nativo x64.

Para obtener más información, consulte [x64 calling convention](https://learn.microsoft.com/cpp/build/x64-calling-convention) (Microsoft Docs).

### Vector call

Visual Studio admite una convención de llamada opcional conocida como `__vectorcall` para la generación de código nativo x64.

* Si el primer parámetro es un entero o un equivalente de puntero, se pasa en RCX. Si es `float`, `double`, `__m128`, `__m128i` o `__m128d`, el parámetro se pasa en XMM0. Si es `__m256`, `__m256i` o `__m256d`, se pasa en YMM0. De lo contrario, el primer parámetro se pasa por la pila.
* Si el segundo parámetro es un entero o un equivalente de puntero, se pasa en RDX. Si es `float`, `double`, `__m128`, `__m128i`, `__m128d`, `__m256`, `__m256i` o `__m256d`, el parámetro se pasa en XMM1/YMM1. De lo contrario, el segundo parámetro se pasa por la pila.
* Si el tercer parámetro es un entero o un equivalente de puntero, se pasa en R8. Si es `float`, `double`, `__m128`, `__m128i`, `__m128d`, `__m256`, `__m256i` o `__m256d`, el parámetro se pasa en XMM2/YMM2. De lo contrario, el tercer parámetro se pasa por la pila.
* Si el cuarto parámetro es un entero o un equivalente de puntero, se pasa en R9. Si es `float`, `double`, `__m128`, `__m128i`, `__m128d`, `__m256`, `__m256i` o `__m256d`, el parámetro se pasa en XMM3/YMM3. De lo contrario, el cuarto parámetro se pasa por la pila.
* Si el quinto parámetro es `float`, `double`, `__m128`, `__m128i`, `__m128d`, `__m256`, `__m256i` o `__m256d`, el parámetro se pasa en XMM4/YMM4. De lo contrario, el quinto parámetro se pasa por la pila.
* Si el sexto parámetro es `float`, `double`, `__m128`, `__m128i`, `__m128d`, `__m256`, `__m256i` o `__m256d`, el parámetro se pasa en XMM5/YMM5. De lo contrario, el sexto parámetro se pasa por la pila.
* Todos los demás parámetros se pasan por la pila.
* Un valor devuelto que cabe en 64 bits se devuelve en RAX. XMM0 se usa para devolver valores `float`, `double`, `__m128`, `__m128i` y `__m128d`. YMM0 se usa para devolver valores `__m256`, `__m256i` o `__m256d`. De lo contrario, el autor de la llamada pasa un puntero a la memoria como argumento 0 en RCX, y RAX debe devolverse con el mismo puntero.

La convención `__vectorcall` también puede controlar tipos de agregado vectorial homogéneo (HVA), que constan de uno o varios tipos vectoriales o de punto flotante del mismo tipo, hasta cuatro miembros (es decir, `struct * { __m128 v[4]; }` es un HVA).

Como parámetro por valor, un HVA se pasará en registros si hay suficiente espacio disponible en XMM0/YMM0 - XMM5/YMM5 después de asignar los demás parámetros. Como valor devuelto, un HVA se devuelve mediante XMM0/YMM0 - XMM3/YMM3.

> [!NOTE]
>
> `__vectorcall` no admite funciones `vararg` ni constructores de C++.

Para obtener más información, consulte lo siguiente:

* [\_\_vectorcall](https://learn.microsoft.com/cpp/cpp/vectorcall) (Microsoft Docs)
* [Introducing 'Vector Calling Convention'](https://devblogs.microsoft.com/cppblog/introducing-vector-calling-convention/) (C++ Team Blog)

## Optimización de todo el programa (`/GL`, `/Gw`, `/LTCG`)

Mientras que las técnicas tradicionales de optimización del compilador pueden optimizar funciones y módulos, la *optimización de todo el programa*, también conocida como *generación de código en tiempo de vinculación (LTCG)*, realiza optimizaciones entre módulos. Esto incluye una asignación y programación de registros mejoradas con un mejor conocimiento de los efectos secundarios, propagación interprocedimental de constantes y rangos, inserción parcial y desvirtualización de llamadas a funciones en objetos cuando es posible.

> [!NOTE]
>
> LTCG también se puede usar en modo incremental para obtener ventajas de rendimiento del código durante la iteración de desarrollo. Para obtener más información, consulte [Speeding up the Incremental Developer Build Scenario](https://devblogs.microsoft.com/cppblog/speeding-up-the-incremental-developer-build-scenario/) (C++ Team Blog).

> Para los proveedores de middleware que distribuyen bibliotecas estáticas de C++ precompiladas, habilitar WPO vincula la biblioteca a una versión específica del conjunto de herramientas del compilador. En este escenario, debe distribuir las bibliotecas sin WPO. Este consejo no se aplica a las DLL ni al código compilado desde el origen.

Para obtener más información, consulte [/GL (Whole Program Optimization)](https://learn.microsoft.com/cpp/build/reference/gl-whole-program-optimization) (Microsoft Docs).

> Visual Studio 2022 (17.5) agregó un nuevo modificador de conformidad `/Zc:checkGwOdr` relacionado con `/Gw`. Consulte [esta entrada de blog](https://devblogs.microsoft.com/cppblog/standards-conformance-improvements-to-gw-in-visual-studio-version-17-5-preview-2/).

### Optimización guiada por perfiles

La optimización guiada por perfiles (PGO) lleva el proceso de LTCG un paso más allá, ya que la optimización de todo el programa se controla mediante seguimientos de rendimiento recopilados en ejecuciones anteriores de la aplicación. Esto mejora la calidad de las optimizaciones existentes, así como las optimizaciones del diseño de funciones, el diseño de bloques y la separación de código para mejorar el espacio de trabajo y la predicción de bifurcaciones.

Para obtener más información, consulte [Profile-guided optimizations](https://learn.microsoft.com/cpp/build/profile-guided-optimizations) (Microsoft Docs).

## Modificador del enlazador `/OPT:REF,ICF`

Estos modificadores eliminan el contenido redundante de los distintos módulos de objeto cuando se vinculan en el ejecutable final. Normalmente, se deshabilitan en las compilaciones de depuración, pero deben estar presentes en las compilaciones de versión.

> [!NOTE]
>
> Para obtener los mejores resultados, asegúrese de compilar con la opción `/Gy` (habilitar vinculación en el nivel de función).

## Modificador del compilador `/GS`

Se recomienda usar la comprobación de búfer en las configuraciones de versión para todo el código. En los casos en los que haya búferes específicos que estén a salvo de amenazas de seguridad, pero el rendimiento parezca verse afectado por la comprobación, use `__declspec(safebuffers)` en la función en lugar de deshabilitar `/GS` globalmente. Para el código de mayor riesgo, use `#pragma strict_gs_check(on)`.

Para obtener más información, consulte [/GS (Buffer Security Check)](https://learn.microsoft.com/cpp/build/reference/gs-buffer-security-check) (Microsoft Docs).

## Modificador del compilador `/homeparams`

El uso de este modificador en compilaciones optimizadas puede aumentar considerablemente la capacidad de depurar las compilaciones de versión de la aplicación. Si se usa en compilaciones de producción, puede simplificar el proceso de análisis y depuración de volcados de bloqueo. Esto agrega una pequeña sobrecarga por almacenar parámetros adicionales en la pila. En la mayoría de los casos, no tiene un efecto apreciable en el rendimiento.

Para obtener más información, consulte [/homeparams (Copy Register Parameters to Stack)](https://learn.microsoft.com/cpp/build/reference/homeparams-copy-register-parameters-to-stack) (Microsoft Docs).

## Modificador del compilador `/Zc:inline`

Este modificador aplica las reglas más estrictas de C++11 para la declaración de funciones insertadas, que requieren que el cuerpo de todas las funciones insertadas esté presente en la misma unidad de compilación que su declaración y su uso. Usar esta marca puede mejorar los tiempos de compilación y reducir considerablemente el tamaño de los archivos .obj. Si las funciones insertadas no cumplen C++11, obtendrá errores LNK2019 en tiempo de vinculación. Este modificador está activado de forma predeterminada al compilar con MSBuild, pero debe agregarse explícitamente al compilar mediante la línea de comandos, CMake, etc.

Para obtener más información, consulte [/Zc:inline (Remove unreferenced COMDAT)](https://learn.microsoft.com/cpp/build/reference/zc-inline-remove-unreferenced-comdat) (Microsoft Docs).

## Modificador del compilador `/Zc:throwingNew`

El estándar de C++ y las plantillas de la biblioteca estándar de C++ requieren que el operador `new` lance una excepción en lugar de devolver `nullptr` cuando se produce un error en una asignación; puede usar `std::nothrow` con `new` para forzar el comportamiento de devolver `nullptr`. Desde hace mucho tiempo, el compilador de Visual C++ genera una comprobación de `null` después de cada llamada a `new`, lo cual es innecesario cuando hay control de excepciones. Al usar este modificador, se eliminan las comprobaciones adicionales.

Para obtener más información, consulte lo siguiente:

* [/Zc:throwingNew (Assume operator new throws)](https://learn.microsoft.com/cpp/build/reference/zc-throwingnew-assume-operator-new-throws) (Microsoft Docs)
* [New in VS 2015: /Zc:throwingNew](https://devblogs.microsoft.com/cppblog/new-in-vs-2015-zcthrowingnew/) (C++ Team Blog)

## Modificador del compilador `/Zc:__cplusplus`

Por motivos históricos, la macro `__cplusplus` de Visual C++ ha devuelto "199711" durante mucho tiempo. A partir de Visual Studio 2017 (actualización 15.7), este nuevo modificador hace que el compilador de Visual C++ devuelva el valor estándar correcto. Una versión futura del compilador lo hará de forma predeterminada, por lo que conviene activarlo cuanto antes para resolver cualquier problema de conformidad pendiente.

Para obtener más información, consulte lo siguiente:

* [/Zc:\_\_cplusplus (Enable updated \_\_cplusplus macro)](https://learn.microsoft.com/cpp/build/reference/zc-cplusplus) (Microsoft Docs)
* [MSVC now correctly reports \_\_cplusplus](https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/) (C++ Team Blog)

## Modificador del compilador `/volatile:iso`

La palabra clave `volatile` tiene una serie de comportamientos extendidos específicos de Microsoft que no son realmente portables, ni siquiera entre generaciones de Visual C++. Debería considerar activar este modificador y, a continuación, asegurarse de no hacer un uso indebido de `volatile` en el código.

Para obtener más información, consulte [/volatile (volatile Keyword Interpretation)](https://learn.microsoft.com/cpp/build/reference/volatile-volatile-keyword-interpretation) (Microsoft Docs).

## Modificador del compilador `/permissive-`

Visual Studio 2017 introdujo un nuevo modificador de conformidad con el estándar para reemplazar el modificador obsoleto `/Za`. Este modificador hace que el compilador emita errores y advertencias al usar comportamientos de extensiones específicas de Microsoft que podrían causar problemas al portar el código a otros compiladores. El uso de `/permissive-` también puede mejorar los tiempos de compilación.

Para obtener más información, consulte lo siguiente:

* [/permissive- (Standards conformance)](https://learn.microsoft.com/cpp/build/reference/permissive-standards-conformance) (Microsoft Docs)
* [Give Visual C++ a Switch to Standard Conformance](https://devblogs.microsoft.com/cppblog/permissive-switch/) (C++ Team Blog)

> [!NOTE]
>
> A partir de Visual Studio 2017 (actualización 15.3), el uso de `/permissive-` también habilita la búsqueda de nombres en dos fases. Parte del código de plantillas de C++ no se compilará con la aplicación correcta del estándar, por lo que puede deshabilitar selectivamente solo esa parte mediante `/Zc:twoPhase-` en lugar de deshabilitar por completo `/permissive-`.
>
> Para obtener más información, consulte lo siguiente:
>
> * [/Zc:twoPhase- (disable two-phase name lookup)](https://learn.microsoft.com/cpp/build/reference/zc-twophase) (Microsoft Docs)
> * [Two-phase name lookup support comes to MSVC](https://devblogs.microsoft.com/cppblog/two-phase-name-lookup-support-comes-to-msvc/) (C++ Team Blog)

Otros modificadores relacionados con la aplicación de la conformidad son [/Zc:lambda](https://learn.microsoft.com/cpp/build/reference/zc-lambda) y [/Zc:templateScope](https://learn.microsoft.com/cpp/build/reference/zc-templatescope).

## Modificador del compilador `/Zc:preprocessor`

Visual Studio 2019 (16.6) incluye un nuevo modificador para habilitar el preprocesador conforme a C99. Este modificador está desactivado de forma predeterminada, pero si la portabilidad del código es una preocupación, debería considerar habilitarlo. Consulte [Announcing full support for a C/C++ conformant preprocessor in MSVC](https://devblogs.microsoft.com/cppblog/announcing-full-support-for-a-c-c-conformant-preprocessor-in-msvc/).

## Modificador del compilador `/ZH:SHA_256`

Tradicionalmente, los símbolos de depuración han usado el hash MD5. Para mejorar la seguridad de la cadena de suministro, se recomienda usar SHA-256 en su lugar. Tenga en cuenta que Visual Studio 2022 usa `/ZH:SHA_256` de forma predeterminada.

> Este modificador es compatible con clang/LLVM a partir de la versión 16.

## Modificadores del enlazador `/NXCOMPAT` y `/SAFESEH`

Estos dos modificadores son implícitos al usar destinos nativos x64. La protección de no ejecución (NX) es obligatoria para los títulos de XBOX, por lo que no puede usar `/NXCOMPAT:NO`.

## Modificador del enlazador `/DYNAMICBASE`

Este modificador habilita el uso de la selección aleatoria del diseño del espacio de direcciones (ASLR) y está activado de forma predeterminada. Tenga en cuenta que es obligatorio para los títulos de XBOX, por lo que no puede usar `/DYNAMICBASE:NO`.

## Modificador del enlazador `/Debug:FASTLINK`

*Para Visual Studio 2019 (16.8) o posterior, las importantes mejoras de rendimiento del enlazador hacen que ya no se recomiende usar `/Debug:FASTLINK`.*

~~Para las compilaciones locales, habilitar este modificador del enlazador puede mejorar considerablemente los tiempos de iteración de compilación.~~

> [!NOTE]
>
> Tenga en cuenta que con `/Debug:FASTLINK` el `pdb` principal del proyecto solo contiene vínculos a los archivos `pdb` que están dispersos por toda la compilación. Si desea compartir o almacenar los símbolos de una compilación con `/Debug:FASTLINK`, puede usar la herramienta de línea de comandos `mspdbcmf.exe` para generar un archivo `pdb` completo.
>
> Para obtener más información, consulte lo siguiente:
>
> * [/DEBUG (Generate Debug Info)](https://learn.microsoft.com/cpp/build/reference/debug-generate-debug-info) (Microsoft Docs)
> * [Faster C++ build cycle in VS 2017 with /Debug:fastlink](https://devblogs.microsoft.com/cppblog/faster-c-build-cycle-in-vs-15-with-debugfastlink/) (C++ Team Blog)

## Bibliotecas

Para las plataformas *Gaming.Xbox.XboxOne.x64* y *Gaming.Xbox.Scarlett.x64*, es importante vincular con `xgameplatform.lib`. Se trata de una biblioteca "paraguas" que incluye todas las API de Win32 compatibles con la consola. **No** vincule con `kernel32.lib`, `onecore.lib`, `onecoreuap.lib` ni `WindowsApps.lib`. No se recomienda mezclar bibliotecas paraguas, ya que puede provocar errores al iniciar el proceso.

Consulte [Microsoft Docs](https://learn.microsoft.com/windows/win32/apiindex/windows-umbrella-libraries) para obtener más información sobre las bibliotecas "paraguas".

### Modificador del enlazador `/NODEFAULTLIB:library`

Se recomienda usar el modificador del enlazador `/NODEFAULTLIB` con una lista específica de nombres de bibliotecas comunes para garantizar que no se usen bibliotecas no compatibles en tiempo de vinculación mediante `#pragma comment(lib,)`.

```
/NODEFAULTLIB:advapi32.lib /NODEFAULTLIB:comctl32.lib /NODEFAULTLIB:comsupp.lib
/NODEFAULTLIB:dbghelp.lib /NODEFAULTLIB:gdi32.lib /NODEFAULTLIB:gdiplus.lib
/NODEFAULTLIB:guardcfw.lib /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:mmc.lib
/NODEFAULTLIB:msimg32.lib /NODEFAULTLIB:msvcole.lib /NODEFAULTLIB:msvcoled.lib
/NODEFAULTLIB:mswsock.lib /NODEFAULTLIB:ntstrsafe.lib /NODEFAULTLIB:ole2.lib
/NODEFAULTLIB:ole2autd.lib /NODEFAULTLIB:ole2auto.lib /NODEFAULTLIB:ole2d.lib
/NODEFAULTLIB:ole2ui.lib /NODEFAULTLIB:ole2uid.lib /NODEFAULTLIB:ole32.lib
/NODEFAULTLIB:oleacc.lib /NODEFAULTLIB:oleaut32.lib /NODEFAULTLIB:oledlg.lib
/NODEFAULTLIB:oledlgd.lib /NODEFAULTLIB:oldnames.lib /NODEFAULTLIB:runtimeobject.lib
/NODEFAULTLIB:shell32.lib /NODEFAULTLIB:shlwapi.lib /NODEFAULTLIB:strsafe.lib
/NODEFAULTLIB:urlmon.lib /NODEFAULTLIB:user32.lib /NODEFAULTLIB:userenv.lib
/NODEFAULTLIB:wlmole.lib /NODEFAULTLIB:wlmoled.lib
/NODEFAULTLIB:onecore.lib
```

> [!NOTE]
>
> Si una biblioteca aparece explícitamente como entrada de vinculación, se seguirá usando aunque figure como biblioteca de `/NODEFAULTLIB`. El modificador solo omite las referencias implícitas.

### Bibliotecas en tiempo de ejecución de Visual C++

El **Símbolo del sistema para desarrolladores de Visual Studio** define las variables de entorno necesarias para localizar estas rutas.

El `/LIBPATH` adecuado para que *Gaming.Xbox.\*.x64* localice las bibliotecas de importación del entorno de ejecución de Visual C++ es `%VCToolsInstallDir%lib\onecore\x64`.

#### Bibliotecas de vínculos dinámicos (DLL)

El Game OS para *Gaming.Xbox.\*.x64* no incluye las bibliotecas DLL del entorno de ejecución de Visual C++. Estas se incluyen en el diseño del título para que el juego pueda iniciarse.

* Para la versión de lanzamiento, necesitará el contenido de `%VCToolsRedistDir%onecore\x64\Microsoft.VC14?.CRT`. Si tiene una combinación de binarios de depuración y de versión en el mismo diseño, querrá incluirlos en todos los diseños.

* Para la depuración, necesitará el contenido de `%VCToolsRedistDir%onecore\debug_nonredist\x64\Microsoft.VC14?.DebugCRT`.

* Para la depuración, *también* necesitará la versión de depuración de `ucrtbased.dll`, que se encuentra en Windows SDK: `%WindowsSdkVerBinPath%x64\ucrt`. La versión de lanzamiento de `ucrtbase.dll` está incluida en el Game OS.

> [!NOTE]
>
> Si usa OpenMP, también necesitará el contenido de `Microsoft.VC14?.OpenMP` o `Microsoft.VC14?.DebugOpenMP`, o ambos.

## Vea también

Ejemplos de [CMakeExample](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Tools/)


## Related topics

- [Recursos del compilador de Visual C++](https://devdocs.xbox.com/es/tools/tools-console/visualstudio/compiler-resources.md)
- [Visual Studio (contenido)](https://devdocs.xbox.com/es/tools/tools-pc/visualstudio/gr-visualstudio-toc.md)
- [Uso de Clang con Microsoft Game Development Kit (GDK) para consolas](https://devdocs.xbox.com/es/tools/tools-console/visualstudio/vs-clang.md)
- [Optimización guiada por perfiles en Visual Studio](https://devdocs.xbox.com/es/tools/tools-console/pgo/pgo_full.md)
- [Visual Studio para el desarrollo en consola](https://devdocs.xbox.com/es/tools/tools-console/visualstudio/visualstudio.md)
