Améliorations de la conformité, changements de comportement et correctifs de bogues de C++ dans Visual Studio 2022

Microsoft C/C++ dans Visual Studio (MSVC) apporte des améliorations de la conformité et des correctifs de bogues dans chaque version. Cet article répertorie les améliorations significatives apportées par version majeure, puis par version. Pour accéder directement aux modifications d’une version spécifique, utilisez les liens de cet article .

Ce document répertorie les modifications apportées à Visual Studio 2022.

Pour connaître les modifications apportées à Visual Studio 2019, consultez les améliorations de conformité C++ dans Visual Studio 2019.
Pour connaître les modifications apportées à Visual Studio 2017, consultez Améliorations de la conformité de C++ dans Visual Studio 2017.
Pour connaître les modifications apportées aux versions antérieures, consultez Visual C++ Nouveautés 2003 à 2015.

Améliorations de la conformité dans Visual Studio 2022 version 17.9

Visual Studio 2022 version 17.9 contient les améliorations de conformité suivantes, les correctifs de bogues et les modifications de comportement dans le compilateur Microsoft C/C++.

Pour obtenir un résumé plus large des modifications apportées à la bibliothèque de modèles standard, consultez STL Changelog VS 2022 17.9.

Application d’un _Alignas type structuré en C

Dans les versions de Visual C++ antérieures à Visual Studio 2022 version 17.9, lorsqu’elles _Alignas apparaissent en regard d’un type de structure dans une déclaration, elle n’a pas été appliquée correctement en fonction de la norme ISO-C. Par exemple :

// compile with /std:c17
#include <stddef.h>
struct Outer
{
    _Alignas(32) struct Inner { int i; } member1;
    struct Inner member2;
};
static_assert(offsetof(struct Outer, member2)==4, "incorrect alignment");

Selon la norme ISO-C, ce code doit être compilé sans émettre static_assert de diagnostic. La _Alignas directive s’applique uniquement à la variable member1membre . Il ne doit pas modifier l’alignement de struct Inner. Toutefois, avant la version 17.9.1 de Visual Studio, le diagnostic « alignement incorrect » a été émis. Le compilateur aligné sur member2 un décalage de 32 octets dans struct Outer.

La correction de ce changement est un changement cassant binaire. Par conséquent, lorsque ce changement de comportement est appliqué, un avertissement est émis. Pour le code précédent, Avertissement C5274, «_Alignas ne s’applique plus au type « Inner » (s’applique uniquement aux objets de données déclarés) » est désormais émis au niveau d’avertissement 1.

Dans les versions précédentes de Visual Studio, _Alignas elle a été ignorée lorsqu’elle apparaît à côté d’une déclaration de type anonyme. Par exemple :

// compile with /std:c17
#include <stddef.h>
struct S {
    _Alignas(32) struct { int anon_member; };
    int k;
};
static_assert(offsetof(struct S, k)==4, "incorrect offsetof");
static_assert(sizeof(struct S)==32, "incorrect size");

Auparavant, les deux static_assert instructions ont échoué lors de la compilation de ce code. Le code se compile maintenant, mais avec les avertissements de niveau 1 suivants :

warning C5274: behavior change: _Alignas no longer applies to the type '<unnamed-tag>' (only applies to declared data objects)
warning C5273: behavior change: _Alignas on anonymous type no longer ignored (promoted members will align)

Si vous souhaitez le comportement précédent, remplacez _Alignas(N) par __declspec(align(N)). Contrairement _Alignasà , declspec(align) peut être appliqué à un type.

__VA_OPT__ est activé en tant qu’extension sous /Zc:preprocessor

__VA_OPT__ a été ajouté à C++20 et C23. Avant son ajout, il n’y avait pas de moyen standard d’éliser une virgule dans une macro variadicique. Pour améliorer la compatibilité descendante, __VA_OPT__ il est activé sous le préprocesseur /Zc:preprocessor basé sur le jeton sur toutes les versions de langage.

Par exemple, cette opération est compilée sans erreur :

#define LOG_WRAPPER(message, ...) WRITE_LOG(__LINE__, message __VA_OPT__(, __VA_ARGS__))

// Failed to build under /std:c11, now succeeds.
LOG_WRAPPER("Log message");
LOG_WRAPPER("Log message with %s", "argument")

Langage C23

Pour C23, les éléments suivants sont disponibles lors de l’utilisation du commutateur du /std:clatest compilateur :

typeof
typeof_unqual

Les éléments suivants sont disponibles pour toutes les versions du langage C :

__typeof__
__typeof_unqual__

Bibliothèque standard C++

Fonctionnalités C++23

  • formattable, range_format, format_kindet set_debug_format() dans le cadre de P2286R8 plages de mise en forme
  • <mdspan> par P0009R18 et les modifications de formulation suivantes qui ont été appliquées à la norme C++23.
  • format() pointeurs par P2510R3.

Améliorations de la conformité dans Visual Studio 2022 version 17.8

Dans Visual Studio 2022 version 17.8, les améliorations de conformité, correctifs de bogues et changements de comportement suivants ont été apportés au compilateur Microsoft C/C++.

/FU émet une erreur

Le compilateur C continuait d’accepter l’option /FU alors qu’il ne prenait plus en charge la compilation managée depuis un certain temps. Il émet maintenant une erreur. Les projets qui passent cette option doivent la limiter aux projets C++/CLI.

Bibliothèque standard C++

Les modules C++23 nommés std et std.compat sont désormais disponibles lors de la compilation avec /std:c++20.

Pour obtenir un résumé plus complet des modifications apportées à la bibliothèque standard C++, consultez le journal des modifications STL VS 2022 17.8.

Améliorations de la conformité dans Visual Studio 2022 version 17.7

Dans Visual Studio 2022 version 17.7, les améliorations de conformité, correctifs de bogues et changements de comportement mis en évidence ci-après ont été apportés au compilateur Microsoft C/C++.

Ajout de /std:clatest au compilateur C

Ce commutateur se comporte comme le commutateur /std:c++latest pour le compilateur C++. Le commutateur active toutes les fonctionnalités du compilateur et de la bibliothèque standard actuellement implémentées pour le prochain projet du standard C ainsi que certaines fonctionnalités expérimentales et en cours.

Bibliothèque standard C++

La bibliothèque <print> est désormais prise en charge. Consultez Sortie au format P2093R14.

Implémentation de views::cartesian_product.

Pour obtenir un résumé plus complet des modifications apportées à la bibliothèque de modèles standard consultez le journal des modifications STL VS 2022 17.7.

Conformité de using

Auparavant, avec la directive using, des noms d’espaces de noms utilisés pouvaient rester visibles par erreur. Cela pouvait entraîner une recherche de nom non qualifiée pour trouver un nom dans un espace de noms, même en l’absence de directive using active.

Voici quelques exemples du nouveau comportement et de l’ancien.
Les références dans les commentaires suivants à « (1) » signifient l’appel à f<K>(t) dans l’espace de noms A :

namespace A
{ 
    template<typename K, typename T> 
    auto f2(T t)
    { 
        return f<K>(t); // (1) Unqualified lookup should not find anything
    } 
} 

namespace B
{ 
    template<typename K, typename T> 
    auto f(T t) noexcept
    { // Previous behavior: This function was erroneously found during unqualified lookup at (1)
        return A::f2<K>(t); 
    } 
} 

namespace C
{ 
    template<typename T> 
    struct S {}; 

    template<typename, typename U> 
    U&& f(U&&) noexcept; // New behavior: ADL at (1) correctly finds this function 
} 

namespace D
{ 
    using namespace B; 

    void h()
    { 
        D::f<void>(C::S<int>()); 
    } 
} 

Le même problème sous-jacent peut entraîner le rejet du code précédemment compilé :

#include <memory>
namespace Addin {}
namespace Gui
{
    using namespace Addin;
}

namespace Addin
{
    using namespace std;
}

// This previously compiled, but now emits error C2065 for undeclared name 'allocator'.
// This should be declared as 'std::allocator<T*>' because the using directive nominating
// 'std' is not active at this point.
template <class T, class U = allocator<T*>>
class resource_list
{
};

namespace Gui
{
    typedef resource_list<int> intlist;
}

Améliorations de la conformité dans Visual Studio 2022 version 17.6

Visual Studio 2022 version 17.6 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants apportés au compilateur Microsoft C/C++.

Les affectations composées volatile ne sont plus déconseillées

C++20 déconseillait l’application de certains opérateurs aux types qualifiés avec volatile. Par exemple, lorsque le code suivant est compilé avec cl /std:c++20 /Wall test.cpp :

void f(volatile int& expr)
{
   ++expr;
}

Le compilateur produit test.cpp(3): warning C5214: applying '++' to an operand with a volatile qualified type is deprecated in C++20.

Dans C++20, les opérateurs d’assignation composée (opérateurs avec la forme @=) étaient déconseillés. Dans C++23, les opérateurs composés exclus dans C++20 ne sont plus déconseillés. Par exemple, dans C++23, le code suivant ne génère pas d’avertissement, comme c’était le cas dans C++20 :

void f(volatile int& e1, int e2)
{
   e1 += e2;
}

Pour plus d’informations sur ce changement, consultez CWG:2654

La réécriture de l’égalité dans les expressions est un changement moins cassant (P2468R2)

Dans C++20, P2468R2 a modifié le compilateur pour accepter du code tel que :

struct S
{
    bool operator==(const S&);
    bool operator!=(const S&);
};
bool b = S{} != S{};

Le compilateur accepte ce code, ce qui signifie que le compilateur est plus strict avec du code tel que :

struct S
{
  operator bool() const;
  bool operator==(const S&);
};

bool b = S{} == S{};

La version 17.5 du compilateur accepte ce programme. La version 17.6 du compilateur la rejette. Pour résoudre ce problème, ajoutez const à operator== pour supprimer l’ambiguïté. Vous pouvez également ajouter un operator!= correspondant à la définition, comme illustré dans l’exemple suivant :

struct S
{
  operator bool() const;
  bool operator==(const S&);
  bool operator!=(const S&);
};

bool b = S{} == S{};

Les versions 17.5 et 17.6 du compilateur Microsoft C/C++ acceptent le programme précédent et les appels S::operator== dans les deux versions.

Le modèle de programmation général décrit dans P2468R2 indique que s’il existe un operator!= correspondant pour un type, il supprime généralement le comportement de la réécriture. L’ajout d’un operator!= correspondant est le correctif suggéré pour le code précédemment compilé en C++17. Pour plus d’informations, consultez Modèle de programmation.

Améliorations de la conformité dans Visual Studio 2022 version 17.4

Visual Studio 2022 version 17.4 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants dans le compilateur Microsoft C/C++.

Types sous-jacents d’enum non délimitée sans type fixe

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. Sous /Zc:enumTypes, nous implémentons désormais correctement le comportement standard.

La norme C++ nécessite que le type sous-jacent d’une enum soit suffisamment grand pour contenir tous les énumérateurs dans cette enum. 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’enum avaient toujours un type sous-jacent de int dans le compilateur Microsoft, quelles que soient les valeurs d’énumérateur.

Lorsqu’elle est activée, l’option /Zc:enumTypes est une changement cassant potentiel de source et de binaire. Elle est désactivée par défaut, et non activée par /permissive-, car le correctif peut affecter la compatibilité binaire. Certains types d’énumération changent de taille lorsque le correctif conforme est activé. Certains en-têtes SDK Windows incluent de telles définitions d’énumération.

Exemple

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

// Previously, failed this static_assert. Now 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. Using /Zc:enumTypes 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
};

Types d’énumérateurs dans une définition d’enum sans type sous-jacent fixe

Dans les versions de Visual Studio antérieures à Visual Studio 2022 version 17.4, le compilateur C++ ne modélisait pas correctement 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 désormais correctement le comportement standard.

La Norme C++ spécifie qu’au sein d’une définition d’énumération sans type sous-jacent fixe, les initialiseurs déterminent les types des énumérateurs. 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).

Lorsqu’elle est activée, l’option /Zc:enumTypes est une changement cassant potentiel de source et de binaire. Elle est désactivée par défaut, et non activée par /permissive-, car le correctif peut affecter la compatibilité binaire. Certains types d’énumération changent de taille lorsque le correctif conforme est activé. Certains en-têtes SDK Windows incluent de telles définitions d’énumération.

Exemple

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. Il doit donc B être initialisé à l’aide sizeof(char)de . 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.

Améliorations de la conformité dans Visual Studio 2022 version 17.3

Visual Studio 2022 version 17.3 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants dans le compilateur Microsoft C/C++.

C : Amélioration de la vérification de la compatibilité des modificateurs entre les pointeurs

Le compilateur C ne comparait pas correctement les modificateurs entre les pointeurs, en particulier void*. Ce défaut pouvait entraîner un diagnostic incorrect d’incompatibilité entre const int** et void*, et de compatibilité entre int* volatile* et void*.

Exemple

void fn(void* pv) { (pv); }

int main()
{
    int t = 42;
    int* pt = &t;
    int* volatile * i = &pt;
    fn(i);    // Now raises C4090
    const int** j = &pt;
    fn(j);    // No longer raises C4090
}

Améliorations de la conformité dans Visual Studio 2022 version 17.2

Visual Studio 2022 version 17.2 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants dans le compilateur Microsoft C/C++.

Avertissements de caractères bidirectionnels inachevés

Visual Studio 2022 version 17.2 ajoute un avertissement C5255 de niveau 3 pour les caractères bidirectionnels Unicode inachevés dans des commentaires et des chaînes. Cet avertissement répond à un souci de sécurité décrit dans Trojan Source : Invisible Vulnerabilities par Nicholas Boucher et Ross Anderson. Pour plus d’informations sur les caractères bidirectionnels Unicode, consultez Unicode® Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM.

L’avertissement C5255 ne concerne que les fichiers qui, après conversion, contiennent des caractères bidirectionnels Unicode. Cet avertissement s’appliquant aux fichiers UTF-8, UTF-16 et UTF-32, l’encodage source approprié doit être fourni. Cette modification est un changement cassant de source.

Exemple (avant/après)

Dans les versions de Visual Studio antérieures à Visual Studio 2022 version 17.2, un caractère bidirectionnel inachevé ne générait pas d’avertissement. Visual Studio 2022 version 17.2 génère l’avertissement C5255 :

// bidi.cpp
int main() {
    const char *access_level = "user";
    // The following source line contains bidirectional Unicode characters equivalent to:
    //    if ( strcmp(access_level, "user\u202e \u2066// Check if admin \u2069 \u2066") ) {
    // In most editors, it's rendered as:
    //    if ( strcmp(access_level, "user") ) { // Check if admin
    if ( strcmp(access_level, "user‮ ⁦// Check if admin ⁩ ⁦") ) {
        printf("You are an admin.\n");
    }
    return 0;
}

/* build output
bidi.cpp(8): warning C5255: unterminated bidirectional character encountered: 'U+202e'
bidi.cpp(8): warning C5255: unterminated bidirectional character encountered: 'U+2066'
*/

Départage from_chars()float

Visual Studio 2022 version 17.2 corrige un bogue dans les règles de départage <charconv>from_chars()float, qui produisait des résultats incorrects. Ce bogue affectait les chaînes décimales qui se trouvaient au milieu exact de valeurs float consécutives à l’intérieur d’une plage étroite. (Les valeurs les plus petites et les plus importantes affectées ont été 32768.009765625 et 131071.98828125, respectivement.) La règle de cravate voulait arrondir à « même », et « même » était « down », mais l’implémentation a mal arrondi « up » (double n’a pas été affectée).) Pour plus d’informations et d’implémentation, consultez microsoft/STL#2366.

Cette modification affecte le comportement du runtime dans la plage de cas spécifiée :

Exemple

// from_chars_float.cpp
#include <cassert>
#include <charconv>
#include <cstdio>
#include <string_view>
#include <system_error>
using namespace std;
int main() {
    const double dbl  = 32768.009765625;
    const auto sv     = "32768.009765625"sv;
    float flt         = 0.0f;
    const auto result = from_chars(sv.data(), sv.data() + sv.size(), flt);
    assert(result.ec == errc{});
    printf("from_chars() returned: %.1000g\n", flt);
    printf("This rounded %s.\n", flt < dbl ? "DOWN" : "UP");
}

Dans les versions antérieures à Visual Studio 2022 version 17.2 :

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp && from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.01171875
This rounded UP.

Dans Visual Studio 2022 versions 17.2 et ultérieures :

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp && from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.0078125
This rounded DOWN.

/Zc:__STDC__ rend __STDC__ disponible pour C

La norme C exige qu’une implémentation de C conforme définisse __STDC__ comme 1. En raison du comportement de l’UCRT, qui n’expose pas les fonctions POSIX quand __STDC__ est 1, il n’est pas possible de définir cette macro pour C par défaut sans introduire de changements cassants dans les versions de langage stable. Visual Studio 2022 versions 17.2 et ultérieures ajoutent une option de conformité /Zc:__STDC__ qui définit cette macro. Il n’existe aucune version négative de l’option. Actuellement, nous prévoyons d’utiliser cette option par défaut pour les futures versions de C.

Cette modification est un changement cassant de source. Elle s’applique lorsque le mode C11 ou C17 est activé, /std:c11 ou /std:c17, avec /Zc:__STDC__.

Exemple

// test__STDC__.c
#include <io.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
#if __STDC__
    int f = _open("file.txt", _O_RDONLY);
    _close(f);
#else
    int f = open("file.txt", O_RDONLY);
    close(f);
#endif
}

/* Command line behavior

C:\Temp>cl /EHsc /W4 /Zc:__STDC__ test__STDC__.c && test__STDC__

*/

Avertissement pour les accolades manquantes

L’avertissement C5246 signale des accolades manquantes pendant l’initialisation agrégée d’un sous-objet. Avant Visual Studio 2022 version 17.2, l’avertissement ne gérait pas le cas d’un struct ou d’une union anonymes.

Cette modification est un changement cassant de source. Elle s’applique lorsque l’avertissement désactivé par défaut C5246 est activé.

Exemple

Dans Visual Studio 2022 versions 17.2 et ultérieures, ce code provoque désormais une erreur :

struct S {
   union {
      float f[4];
      double d[2];
   };
};

void f()
{
   S s = { 1.0f, 2.0f, 3.14f, 4.0f };
}

/* Command line behavior
cl /Wall /c t.cpp

t.cpp(10): warning C5246: 'anonymous struct or union': the initialization of a subobject should be wrapped in braces
*/

Pour résoudre ce problème, ajoutez des accolades à l’initialiseur :

void f()
{
   S s = { { 1.0f, 2.0f, 3.14f, 4.0f } };
}

Améliorations de la conformité dans Visual Studio 2022 version 17.1

Visual Studio 2022 version 17.1 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants dans le compilateur Microsoft C/C++.

Détecter les valeurs par défaut de capture mal formées dans les expressions lambda non locales

La Norme C++ autorise uniquement une expression lambda dans une portée de bloc à avoir une capture par défaut. Dans Visual Studio 2022 versions 17.1 et ultérieures, le compilateur détecte quand une valeur par défaut de capture n’est pas autorisée dans une expression lambda non locale. Il émet un nouvel avertissement de niveau 4, C5253.

Cette modification est un changement cassant de source. Elle s’applique en tout mode qui utilise le nouveau processeur lambda : /Zc:lambda, /std:c++20 ou /std:c++latest.

Exemple

Dans Visual Studio 2022 version 17.1, ce code émet désormais une erreur :

#pragma warning(error:5253)

auto incr = [=](int value) { return value + 1; };

// capture_default.cpp(3,14): error C5253: a nonlocal lambda cannot have a capture default
// auto incr = [=](int value) { return value + 1; };
//              ^

Pour résoudre ce problème, supprimez le défaut de capture :

#pragma warning(error:5253)

auto incr = [](int value) { return value + 1; };

C4028 est maintenant C4133 pour les opérations de fonction à pointeur

Avant Visual Studio 2022 version 17.1, le compilateur générait un message d’erreur incorrect sur certaines comparaisons de pointeur à fonction dans le code C. Le message incorrect était généré lorsque vous compariez deux pointeurs de fonction qui avaient le même nombre d’arguments mais des types incompatibles. Désormais, nous émettons un avertissement différent dénonçant une incompatibilité de pointeur à fonction plutôt qu’une discordance de paramètre de fonction.

Cette modification est un changement cassant de source. Elle s’applique lorsque le code est compilé en tant que C.

Exemple

int f1(int); 
int f2(char*); 
int main(void) 
{ 
    return (f1 == f2); 
}
// Old warning:
// C4028: formal parameter 1 different from declaration
// New warning:
// C4113: 'int (__cdecl *)(char *)' differs in parameter lists from 'int (__cdecl *)(int)'

Erreur sur un élément static_assert non dépendant

Dans Visual Studio 2022 version 17.1 et ultérieure, si l’expression associée à un static_assert n’est pas une expression dépendante, le compilateur évalue l’expression lorsqu’elle est analysée. Si l’expression prend la valeur false, le compilateur émet une erreur. Auparavant, si la static_assert se trouvait dans le corps d’un modèle de fonction (ou dans le corps d’une fonction membre d’un modèle de classe), le compilateur n’effectuait pas cette analyse.

Cette modification est un changement cassant de source. Elle s’applique en tout mode impliquant /permissive- ou /Zc:static_assert. Ce changement de comportement peut être désactivé à l’aide de l’option de compilateur de /Zc:static_assert-.

Exemple

Dans Visual Studio 2022 versions 17.1 et ultérieures, ce code provoque désormais une erreur :

template<typename T>
void f()
{
   static_assert(false, "BOOM!");
}

Pour résoudre ce problème, rendez l’expression dépendante. Par exemple :

template<typename>
constexpr bool dependent_false = false;

template<typename T>
void f()
{
   static_assert(dependent_false<T>, "BOOM!");
}

Avec cette modification, le compilateur n’émet une erreur que si le modèle de fonction f est instancié.

Améliorations de la conformité dans Visual Studio 2022 version 17.0

Visual Studio 2022 version 17.0 contient les améliorations de conformité, les correctifs de bogues et les changements de comportement suivants dans le compilateur Microsoft C/C++.

Avertissement sur la largeur de champ de bits pour un type d’énumération

Lorsque vous déclarez une instance d’un type d’énumération en tant que champ de bits, la largeur du champ de bits doit pouvoir accueillir toutes les valeurs possibles de l’énumération. Sinon, le compilateur émet un message de diagnostic. Prenons l’exemple suivant :

enum class E : unsigned { Zero, One, Two };

struct S {
  E e : 1;
};

Un programmeur pourrait s’attendre à ce que le membre de classe S::e puisse contenir l’une des valeurs enum nommées explicitement. Compte tenu du nombre d’éléments d’énumération, ce n’est pas possible. Le champ de bits ne peut pas couvrir la plage de valeurs explicitement fournies de E (conceptuellement, le domaine de E). Pour résoudre le problème lié au fait que la largeur du champ de bits n’est pas suffisante pour le domaine de l’énumération, un nouvel avertissement (désactivé par défaut) est ajouté à MSVC :

t.cpp(4,5): warning C5249: 'S::e' of type 'E' has named enumerators with values that cannot be represented in the given bit field width of '1'.
  E e : 1;
    ^
t.cpp(1,38): note: see enumerator 'E::Two' with value '2'
enum class E : unsigned { Zero, One, Two };
                                     ^

Ce comportement de compilateur est un changement cassant de source et de binaire qui affecte tous les modes /std et /permissive.

Erreur lors de la comparaison de pointeur ordonné à nullptr ou 0

La Norme C++ autorisait par inadvertance une comparaison de pointeur ordonné à nullptr ou 0. Par exemple :

bool f(int *p)
{
   return p >= 0;
}

Le document WG21 N3478 a supprimé cette omission. Cette modification est implémentée dans MSVC. Lorsque l’exemple est compilé à l’aide /permissive- (et /diagnostics:caret), il émet l’erreur suivante :

t.cpp(3,14): error C7664: '>=': ordered comparison of pointer and integer zero ('int *' and 'int')
    return p >= 0;
             ^

Ce comportement de compilateur est un changement cassant de source et de binaire qui affecte le code compilé à l’aide de /permissive- dans tous les modes /std.

Voir aussi

Conformité du langage Microsoft C/C++