Share via


/Zc:enumTypes (Habilitar la deducción de tipo de enumeración)

La /Zc:enumTypes opción del compilador habilita la deducción del tipo subyacente y del tipo enumerador conformes enum a C++.

Sintaxis

/Zc:enumTypes[-]

Comentarios

La /Zc:enumTypes opción del compilador implementa el comportamiento de conformidad de C++ estándar para la deducción de tipos base de enumeración y los tipos de enumeradores.

La /Zc:enumTypes opción es nueva en Visual Studio 2022, versión 17.4. Esta opción está desactivada de forma predeterminada y no está habilitada por /permissive-. Para deshabilitar explícitamente la opción, use /Zc:enumTypes-.

Cuando está habilitada, la opción /Zc:enumTypes es un posible cambio importante de archivo binario y de origen. Algunos tipos de enumeración cambian el tamaño cuando la opción conforme /Zc:enumTypes está habilitada. Algunos encabezados de Windows SDK incluyen estas definiciones de enumeración.

El estándar de C++ requiere que el tipo subyacente de una enumeración sea lo suficientemente grande como para contener todos los enumeradores declarados en él. Los enumeradores suficientemente grandes pueden establecer el tipo subyacente de enum en unsigned int, long long o unsigned long long. Anteriormente, estos tipos de enumeración siempre tenían un tipo subyacente en el compilador de int Microsoft, independientemente de los valores del enumerador.

El estándar de C++ también especifica que, dentro de una definición de enumeración que no tiene ningún tipo subyacente fijo, los tipos de enumeradores se determinan mediante sus inicializadores. O bien, para los enumeradores sin inicializador, por el tipo del enumerador anterior (teniendo en cuenta el desbordamiento). Anteriormente, estos enumeradores siempre recibían el tipo deducido de la enumeración, con un marcador de posición para el tipo subyacente (normalmente int).

En versiones de Visual Studio anteriores a Visual Studio 2022 versión 17.4, el compilador de C++ no determinaba correctamente el tipo subyacente de una enumeración sin ámbito sin tipo base fijo. El compilador tampoco modeló correctamente los tipos de enumeradores. Podía suponer un tipo incorrecto en enumeraciones sin un tipo subyacente fijo antes de la llave de cierre de la enumeración. En /Zc:enumTypes, el compilador implementa correctamente el comportamiento estándar.

Ejemplo: Tipo subyacente de sin ámbito enum sin tipo fijo

enum Unsigned
{
    A = 0xFFFFFFFF // Value 'A' does not fit in 'int'.
};

// Previously, this static_assert failed. It passes with /Zc:enumTypes.
static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned int>);

template <typename T>
void f(T x)
{
}

int main()
{
    // Previously called f<int>, now calls f<unsigned int>.
    f(+A);
}

// Previously, this enum would have an underlying type of `int`,
// but Standard C++ requires this to have a 64-bit underlying type.
// The /Zc:enumTypes option changes the size of this enum from 4 to 8,
// which could impact binary compatibility with code compiled with an
// earlier compiler version, or without the switch.
enum Changed
{
    X = -1,
    Y = 0xFFFFFFFF
};

Ejemplo: Enumeradores dentro de una enum definición sin ningún tipo subyacente fijo

enum Enum {
    A = 'A',
    B = sizeof(A)
};

static_assert(B == 1); // previously failed, now succeeds under /Zc:enumTypes

En este ejemplo, el enumerador A debe tener el tipo char antes de la llave de cierre de la enumeración, por lo que B se debe inicializar mediante sizeof(char). Antes de la corrección /Zc:enumTypes, A tenía el tipo de enumeración Enum con un tipo subyacente deducido int y B se inicializaba mediante sizeof(Enum), o 4.

Para establecer esta opción del compilador en Visual Studio

  1. 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.

  2. Seleccione la página de propiedades Propiedades de configuración>C/C++>Línea de comandos.

  3. En Opciones adicionales, agregue /Zc:enumTypes o /Zc:enumTypes-. Haga clic en Aceptar o en Aplicar para guardar los cambios.

Consulte también

/Zc (Conformidad)
/std (Especificar la versión estándar del lenguaje)