Partilhar via


/Zc:enumTypes (Habilitar dedução de tipo de enumeração)

A /Zc:enumTypes opção do compilador permite a dedução de enum tipo subjacente e de tipo de enumerador em conformidade com C++.

Sintaxe

/Zc:enumTypes[-]

Comentários

A /Zc:enumTypes opção do compilador implementa o comportamento em conformidade com o C++ padrão para dedução de tipos base de enumeração e os tipos de enumeradores.

A /Zc:enumTypes opção é nova no Visual Studio 2022 versão 17.4. Essa opção está desativada por padrão e não é ativada pelo /permissive-. Para desativar explicitamente a opção, use /Zc:enumTypes-.

Quando habilitada, a opção /Zc:enumTypes é uma possível alteração de falha de origem e binária. Alguns tipos de enumeração mudam de tamanho quando a opção de /Zc:enumTypes conformidade está habilitada. Determinados cabeçalhos do SDK do Windows incluem essas definições de enumeração.

O padrão C++ requer que o tipo subjacente de uma enumeração seja grande o suficiente para conter todos os enumeradores declarados nela. Enumeradores suficientemente grandes podem definir o tipo subjacente do enum como unsigned int, long long ou unsigned long long. Anteriormente, esses tipos de enumeração sempre tinham um tipo subjacente de no compilador da int Microsoft, independentemente dos valores do enumerador.

O padrão C++ também especifica que, dentro de uma definição de enumeração que não tem nenhum tipo subjacente fixo, os tipos de enumeradores são determinados por seus inicializadores. Ou, para os enumeradores sem inicializador, pelo tipo do enumerador anterior (contabilizando o estouro). Anteriormente, esses enumeradores sempre recebiam o tipo deduzido da enumeração, com um espaço reservado para o tipo subjacente (normalmente int).

Em versões do Visual Studio antes do Visual Studio 2022 versão 17.4, o compilador C++ não determinava corretamente o tipo subjacente de uma enumeração sem escopo sem tipo base fixo. O compilador também não modelou corretamente os tipos de enumeradores. Ele poderia assumir um tipo incorreto em enumerações sem um tipo subjacente fixo antes da chave de fechamento da enumeração. Em /Zc:enumTypes, o compilador implementa corretamente o comportamento padrão.

Exemplo: tipo subjacente de sem escopo enum sem tipo fixo

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
};

Exemplo: enumeradores em uma enum definição sem tipo subjacente fixo

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

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

Neste exemplo, o enumerador A deve ter o tipo char antes da chave de fechamento da enumeração, portanto B deve ser inicializado usando sizeof(char). Antes da correção /Zc:enumTypes, A tinha um tipo de enumeração Enum com um tipo subjacente deduzido int e B era inicializado usando sizeof(Enum) ou 4.

Para definir essa opção do compilador no 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. Selecione a página de propriedades Propriedades de Configuração>C/C++>Linha de Comando.

  3. Em Opções adicionais, adicione /Zc:enumTypes ou /Zc:enumTypes-. Escolha OK ou Aplicar para salvar as alterações.

Confira também

/Zc (Conformidade)
/std (Especificar a versão padrão da linguagem)