Share via


/Zc:enumTypes (Activer la déduction de type d’énumération)

L’option /Zc:enumTypes du compilateur active la déduction de type sous-jacent et d’énumérateur conforme enum C++.

Syntaxe

/Zc:enumTypes[-]

Notes

L’option /Zc:enumTypes du compilateur implémente le comportement conforme standard C++ pour la déduction des types de base d’énumération et les types d’énumérateurs.

L’option /Zc:enumTypes est nouvelle dans Visual Studio 2022 version 17.4. Cette option est désactivée par défaut et n’est pas activée par /permissive-. Pour désactiver explicitement l’option, utilisez /Zc:enumTypes-.

Lorsqu’elle est activée, l’option /Zc:enumTypes est une changement cassant potentiel de source et de binaire. Certains types d’énumération changent de taille lorsque l’option conforme /Zc:enumTypes est activée. Certains en-têtes SDK Windows incluent de telles définitions d’énumération.

La norme C++ exige que le type sous-jacent d’une énumération soit suffisamment grand pour contenir tous les énumérateurs déclarés dans celui-ci. Des énumérateurs suffisamment grands peuvent définir le type sous-jacent de l’enum sur unsigned int, long long ou unsigned long long. Auparavant, ces types d’énumération avaient toujours un type int sous-jacent dans le compilateur Microsoft, quelles que soient les valeurs d’énumérateur.

La norme C++ spécifie également que, dans une définition d’énumération qui n’a aucun type sous-jacent fixe, les types d’énumérateurs sont déterminés par leurs initialiseurs. Ou bien, pour les énumérateurs sans initialiseur, par le type de l’énumérateur précédent (en tenant compte du dépassement). Auparavant, ces énumérateurs recevaient toujours le type déduit de l’énumération, avec un espace réservé pour le type sous-jacent (généralement int).

Dans les versions de Visual Studio antérieures à Visual Studio 2022 version 17.4, le compilateur C++ ne déterminait pas correctement le type sous-jacent d’une énumération non délimitée sans type de base fixe. Le compilateur n’a pas non plus correctement modélisé les types d’énumérateurs. Il pouvait supposer un type incorrect dans les énumérations sans type sous-jacent fixe avant l’accolade fermante de l’énumération. Sous /Zc:enumTypes, le compilateur implémente correctement le comportement standard.

Exemple : Type sous-jacent non spécifié enum sans type fixe

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

Exemple : énumérateurs dans une enum définition sans type sous-jacent fixe

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

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

Dans cet exemple, l’énumérateur A doit avoir un type char avant l’accolade fermante de l’énumération. Par conséquent, B doit être initialisé avec sizeof(char). Avant le correctif /Zc:enumTypes, A avait un type d’énumération Enum avec un type sous-jacent déduit int, et B était initialisé avec sizeof(Enum) ou 4.

Pour définir cette option de compilateur dans Visual Studio

  1. Ouvrez la boîte de dialogue Pages de propriété du projet. Pour plus d’informations, consultez Définir le compilateur C++ et les propriétés de build dans Visual Studio.

  2. Sélectionnez la page de propriétés Propriétés de configuration>C/C++>Ligne de commande.

  3. Dans d’autres options, ajoutez /Zc:enumTypes ou /Zc:enumTypes-. Choisissez OK ou Appliquer pour enregistrer vos modifications.

Voir aussi

/Zc (Conformité)
/std (Spécifier la version du standard du langage)