Mejoras en la conformidad de C++, cambios de comportamiento y correcciones de errores en Visual Studio 2022

Microsoft C/C++ en Visual Studio (MSVC) hace mejoras de conformidad y corrige errores en cada versión. En este artículo se enumeran las mejoras notables por versión principal y luego por versión. Para ir directamente a los cambios de una versión específica, use los vínculos En este artículo .

En este documento se enumeran los cambios en Visual Studio 2022.

Para ver los cambios en Visual Studio 2019, consulte Mejoras de conformidad de C++ en Visual Studio 2019.
Para conocer los cambios en Visual Studio 2017, consulte Mejoras de conformidad de C++ en Visual Studio 2017.
Para ver los cambios en versiones anteriores, vea Novedades de Visual C++ a 2003 a 2015.

Mejoras de conformidad en Visual Studio 2022, versión 17.9

La versión 17.9 de Visual Studio 2022 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento en el compilador de Microsoft C/C++.

Para obtener un resumen más amplio de los cambios realizados en la biblioteca de plantillas estándar, vea STL Changelog VS 2022 17.9.

Aplicación de _Alignas en un tipo estructurado en C

En versiones de Visual C++ anteriores a la versión 17.9 de Visual Studio 2022, cuando _Alignas aparecía junto a un tipo de estructura en una declaración, no se aplicaba correctamente según el estándar ISO-C. Por ejemplo:

// 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");

Según el estándar ISO-C, este código debe compilarse sin emitir static_assert un diagnóstico. La _Alignas directiva solo se aplica a la variable member1miembro . No debe cambiar la alineación de struct Inner. Sin embargo, antes de la versión 17.9.1 de Visual Studio, se emitió el diagnóstico "alineación incorrecta". El compilador se alinea con member2 un desplazamiento de 32 bytes dentro de struct Outer.

Corregir este es un cambio importante binario, por lo que cuando se aplica este cambio en el comportamiento se emite una advertencia. Para el código anterior, advertencia C5274, "_Alignas ya no se aplica al tipo "Inner" (solo se aplica a objetos de datos declarados)" ahora se emite en el nivel de advertencia 1.

En versiones anteriores de Visual Studio, _Alignas se omitía cuando aparecía junto a una declaración de tipo anónimo. Por ejemplo:

// 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");

Anteriormente, se produjo un error en ambas static_assert instrucciones al compilar este código. El código ahora se compila, pero con las siguientes advertencias de nivel 1:

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 desea el comportamiento anterior, reemplace por _Alignas(N)__declspec(align(N)). A diferencia de _Alignas, declspec(align) se puede aplicar a un tipo.

__VA_OPT__ está habilitado como una extensión en /Zc:preprocessor

__VA_OPT__ se agregó a C++20 y C23. Antes de su adición, no había una manera estándar de esquiar una coma en una macro variádica. Para proporcionar una mejor compatibilidad con versiones anteriores, __VA_OPT__ está habilitado en el preprocesador /Zc:preprocessor basado en tokens en todas las versiones de lenguaje.

Por ejemplo, esto ahora se compila sin error:

#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")

Lenguaje C23

Para C23, los siguientes están disponibles al usar el /std:clatest modificador del compilador:

typeof
typeof_unqual

Los siguientes están disponibles para todas las versiones del lenguaje C:

__typeof__
__typeof_unqual__

Biblioteca estándar de C++

Características de C++23

  • formattable, range_format, format_kindy set_debug_format() como parte de los intervalos de formato de P2286R8
  • <mdspan> por P0009R18 y los cambios de redacción posteriores que se aplicaron al estándar de C++23.
  • format() punteros por P2510R3.

Mejoras de cumplimiento en Visual Studio 2022, versión 17.8

Visual Studio 2022, versión 17.8 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

/FU emite un error

El compilador C usado para aceptar la opción/FU, aunque no admita la compilación administrada durante algún tiempo. Ahora emite un error. Los proyectos que pasan esta opción solo deben restringirlo a proyectos de C++/CLI.

Biblioteca estándar de C++

Los módulos con nombre C++23 std y std.compat ahora están disponibles al compilar con /std:c++20.

Para obtener un resumen más amplio de los cambios realizados en la biblioteca Estándar de C++, consulte STL Changelog VS 2022 17.8.

Mejoras de cumplimiento en Visual Studio 2022, versión 17.7

Visual Studio 2022, versión 17.7 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Se ha agregado /std:clatest al compilador de C

Este modificador se comporta como el modificador /std:c++latest del compilador de C++. El modificador habilita todas las características del compilador y de la biblioteca estándar implementadas actualmente y propuestas para el siguiente borrador del estándar de C, así como algunas características en curso y experimentales.

Biblioteca estándar de C++

Ahora se admite la biblioteca <print>. Consulte P2093R14 salida con formato.

Implementadoviews::cartesian_product.

Para obtener un resumen más amplio de los cambios realizados en la biblioteca de plantillas Estándar, consulte STL Changelog VS 2022 17.7.

usingconformidad

Anteriormente, la directiva using podía hacer que los nombres de los espacios de nombres usados permanecieran visibles cuando no debían. Esto podía provocar que la búsqueda de nombres no cualificados encontrara un nombre en un espacio de nombres aunque no hubiera ninguna directiva using activa.

Estos son algunos ejemplos del comportamiento nuevo y antiguo.
Las referencias de los siguientes comentarios a "(1)" significan la llamada a f<K>(t) en el espacio de nombres 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>()); 
    } 
} 

El mismo problema subyacente puede provocar que el código que antes se compilaba ahora sea rechazado:

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

Mejoras de cumplimiento en Visual Studio 2022, versión 17.6

Visual Studio 2022, versión 17.6 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Las asignaciones volatile compuestas ya no están en desuso

En C++20 se dejó de usar la aplicación de determinados operadores a tipos calificados con volatile. Por ejemplo, cuando se compila el siguiente código con cl /std:c++20 /Wall test.cpp:

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

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

En C++20, se dejaron de usar los operadores de asignaciones compuestas (operadores de tipo @=). En C++23, los operadores compuestos excluidos en C++20 ya no están en desuso. Por ejemplo, en C++23, el siguiente código no genera una advertencia, mientras que sí lo hace en C++20:

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

Para obtener más información sobre este cambio, consulte CWG:2654.

La reescritura de igualdad en expresiones no es un cambio importante (P2468R2)

En C++20, P2468R2 cambió el compilador para aceptar código como el siguiente:

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

El compilador acepta este código, lo que significa que el compilador es más estricto con código como el siguiente:

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

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

La versión 17.5 del compilador acepta este programa. La versión 17.6 del compilador lo rechaza. Para corregirlo, agregue const a operator== para eliminar la ambigüedad. O bien agregue un operator!= correspondiente a la definición como se muestra en el siguiente ejemplo:

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

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

Las versiones 17.5 y 17.6 del compilador de Microsoft C/C++ aceptan el programa anterior y llaman a S::operator==.

El modelo de programación general descrito en P2468R2 indica que si hay un operator!= correspondiente para un tipo, normalmente suprime el comportamiento de reescritura. Agregar un operator!= correspondiente es la corrección que se recomienda para el código compilado anteriormente en C++17. Si desea obtener más información, consulte Modelo de programación.

Mejoras de conformidad en Visual Studio 2022, versión 17.4

Visual Studio 2022, versión 17.4 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Tipos subyacentes de enum sin ámbito sin tipo fijo

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. En /Zc:enumTypes, ahora implementamos correctamente el comportamiento estándar.

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

Cuando está habilitada, la opción /Zc:enumTypes es un posible cambio importante de archivo binario y de origen. Está desactivada de manera predeterminada y no la habilita /permissive-, porque la corrección podría afectar a la compatibilidad binaria. Algunos tipos de enumeración cambian de tamaño cuando se habilita la corrección compatible. Algunos encabezados de Windows SDK incluyen estas definiciones de enumeración.

Ejemplo

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

Tipos de enumeradores dentro de una definición de enum sin ningún tipo subyacente fijo

En versiones de Visual Studio anteriores a Visual Studio 2022 versión 17.4, el compilador de C++ no modelaba 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, ahora el compilador implementa correctamente el comportamiento estándar.

El estándar C++ especifica que, en la definición de una enumeración sin un tipo subyacente fijo, los inicializadores determinan los tipos de enumeradores. 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).

Cuando está habilitada, la opción /Zc:enumTypes es un posible cambio importante de archivo binario y de origen. Está desactivada de manera predeterminada y no la habilita /permissive-, porque la corrección podría afectar a la compatibilidad binaria. Algunos tipos de enumeración cambian de tamaño cuando se habilita la corrección compatible. Algunos encabezados de Windows SDK incluyen estas definiciones de enumeración.

Ejemplo

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 debe inicializarse 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.

Mejoras de cumplimiento en Visual Studio 2022, versión 17.3

Visual Studio 2022, versión 17.3 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

C: se ha mejorado la comprobación de compatibilidad del modificador entre punteros

El compilador de C no comparaba correctamente los modificadores entre punteros, especialmente void*. Este defecto podía dar lugar a un diagnóstico incorrecto de incompatibilidad entre const int** y void* y compatibilidad entre int* volatile* y void*.

Ejemplo

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
}

Mejoras de cumplimiento en Visual Studio 2022, versión 17.2

Visual Studio 2022, versión 17.2 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Advertencias de caracteres bidireccionales no terminados

La versión 17.2 de Visual Studio 2022 agrega la advertencia de nivel 3 C5255 para los caracteres bidireccionales Unicode no terminados en comentarios y cadenas. La advertencia aborda una preocupación de seguridad descrita en Origen de troyanos: vulnerabilidades invisibles de Nicholas Boucher y Ross Anderson. Para obtener más información sobre los caracteres bidireccionales Unicode, vea Anexo del estándar Unicode® 9: ALGORITMO BIRECCIONAL DE UNICODE.

La advertencia C5255 solo aborda los archivos que, después de la conversión, contienen caracteres bidireccionales Unicode. Esta advertencia se aplica a los archivos UTF-8, UTF-16 y UTF-32, por lo que se debe proporcionar la codificación de origen adecuada. Este cambio se trata de un cambio que afecta directamente al código fuente.

Ejemplo (antes y después)

En las versiones de Visual Studio anteriores a la versión 17.2 de Visual Studio 2022, un carácter bidireccional no terminado no generaba una advertencia. En la versión 17.2 de Visual Studio 2022 se produce la advertencia 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'
*/

from_chars()float desempate

La versión 17.2 de Visual Studio 2022 corrige un error en las reglas de desempate <charconv>from_chars()float que producían resultados incorrectos. Este error afectaba a las cadenas decimales que estaban en el punto medio exacto de los valores consecutivos float, dentro de un intervalo estrecho. (Los valores más pequeños y más grandes afectados fueron 32768.009765625 y 131071.98828125, respectivamente). La regla del desempate quería redondear a "incluso", e "incluso" era "abajo", pero la implementación redondeada incorrectamente "arriba" (double no se vio afectada). Para obtener más información e información sobre la implementación, consulte microsoft/STL#2366.

Este cambio afecta al comportamiento del entorno de ejecución en el intervalo de casos especificado.

Ejemplo

// 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");
}

En las versiones anteriores a la versión 17.2 de Visual Studio 2022:

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.

En Visual Studio 2022, versión 17.2 y posteriores:

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__ pone __STDC__ a disposición de C

El estándar de C requiere que una implementación de C conforme defina __STDC__ como 1. Debido al comportamiento de UCRT, que no expone funciones POSIX cuando __STDC__ es 1, no es posible definir esta macro para C de forma predeterminada sin introducir cambios importantes en las versiones de lenguaje estable. Visual Studio 2022, versión 17.2 y posteriores, agrega una opción de conformidad, /Zc:__STDC__, que define esta macro. No hay ninguna versión negativa de la opción. Actualmente, tenemos previsto usar esta opción de forma predeterminada para versiones futuras de C.

Este cambio se trata de un cambio que afecta directamente al código fuente. Se aplica cuando el modo C11 o C17 está habilitado, /std:c11 o /std:c17, junto con /Zc:__STDC__.

Ejemplo

// 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__

*/

Advertencia para llaves que faltan

La advertencia C5246 notifica que faltan llaves durante la inicialización agregada de un subobjeto. Antes de la versión 17.2 de Visual Studio 2022, la advertencia no controlaba el caso de un struct o union anónimo.

Este cambio se trata de un cambio que afecta directamente al código fuente. Se aplica cuando está habilitada la advertencia C5246 desactivada de forma predeterminada.

Ejemplo

En la versión 17.2 de Visual Studio 2022, este código ahora produce un error:

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
*/

Para resolver este problema, agregue llaves al inicializador:

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

Mejoras de cumplimiento en Visual Studio 2022, versión 17.1

Visual Studio 2022, versión 17.1 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Detección de valores predeterminados de captura con un formato incorrecto en expresiones lambda no locales

El estándar de C++ solo permite que una expresión lambda en el ámbito de bloque tenga un valor predeterminado de captura. En Visual Studio 2022, versiones 17.1 y posteriores, el compilador detecta cuándo no se permite un valor predeterminado de captura en una expresión lambda no local. Emite una nueva advertencia de nivel 4, C5253.

Este cambio se trata de un cambio que afecta directamente al código fuente. Se aplica en cualquier modo que use el nuevo procesador lambda: /Zc:lambda, /std:c++20o /std:c++latest.

Ejemplo

En Visual Studio 2022 versión 17.1, este código ahora emite un error:

#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; };
//              ^

Para corregir este problema, quite el valor predeterminado de captura:

#pragma warning(error:5253)

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

C4028 ahora es C4133 para operaciones de función a puntero

Antes de la versión 17.1 de Visual Studio 2022, el compilador notificaba un mensaje de error incorrecto en determinadas comparaciones de puntero a función en el código de C. Se informó del mensaje incorrecto al comparar dos punteros de función que tenían los mismos recuentos de argumentos, pero tipos incompatibles. Ahora, se emite una advertencia diferente que se queja sobre la incompatibilidad de puntero a función en lugar del error de coincidencia de parámetros de función.

Este cambio se trata de un cambio que afecta directamente al código fuente. Se aplica cuando el código se compila como C.

Ejemplo

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)'

Error en static_assert no dependiente

En Visual Studio 2022, versión 17.1 y posteriores, si la expresión asociada a no static_assert es una expresión dependiente, el compilador evalúa la expresión cuando se analiza. Si la expresión se evalúa como false, el compilador emite un error. Anteriormente, si static_assert estaba dentro del cuerpo de una plantilla de función (o dentro del cuerpo de una función miembro de una plantilla de clase), el compilador no realizaría este análisis.

Este cambio se trata de un cambio que afecta directamente al código fuente. Se aplica en cualquier modo que implique /permissive- o /Zc:static_assert. Este cambio de comportamiento se puede deshabilitar mediante la opción del compilador /Zc:static_assert-.

Ejemplo

En la versión 17.1 de Visual Studio 2022, este código ahora produce un error:

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

Para corregir este problema, haga que la expresión sea dependiente. Por ejemplo:

template<typename>
constexpr bool dependent_false = false;

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

Con este cambio, el compilador solo emite un error si se crea una instancia de la plantilla de función f.

Mejoras de conformidad en Visual Studio 2022, versión 17.0

Visual Studio 2022, versión 17.0 contiene las siguientes mejoras de conformidad, correcciones de errores y cambios de comportamiento del compilador de Microsoft C/C++.

Advertencia sobre el ancho del campo de bits para el tipo de enumeración

Al declarar una instancia de un tipo de enumeración como un campo de bits, el ancho del campo de bits tiene que alojar todos los valores posibles de la enumeración. De lo contrario, el compilador emite un mensaje de diagnóstico. Considere este ejemplo:

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

struct S {
  E e : 1;
};

Un programador podría esperar que el miembro de la clase S::e pueda contener cualquiera de los valores proporcionados explícitamente con nombre enum. Dado el número de elementos de enumeración, esto no es posible. El campo de bits no puede cubrir el intervalo de valores proporcionados de forma explícita de E (conceptualmente, el dominio de E). Para solucionar el problema de que el ancho del campo de bits no es lo suficientemente grande para el dominio de la enumeración, se agrega una nueva advertencia (desactivada de manera predeterminada) a 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 };
                                     ^

Este comportamiento del compilador es un cambio importante de origen y binario que afecta a todos los modos /std y /permissive .

Error en la comparación de punteros ordenados con nullptr o 0

El estándar de C++ permitía accidentalmente una comparación de puntero ordenada con nullptr o 0. Por ejemplo:

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

El documento WG21 N3478 ha quitado esta supervisión. Este cambio se implementa en MSVC. Cuando el ejemplo se compila mediante /permissive- (y /diagnostics:caret ), emite el error siguiente:

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

Este comportamiento del compilador es un cambio importante de origen y binario que afecta al código compilado mediante los modos /permissive- y /std .

Vea también

Conformidad del lenguaje Microsoft C/C++