This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug fixes in every release. This article lists the significant improvements by major release, then by version. To jump directly to the changes for a specific version, use the In this article links at the top of this article.
This document lists the changes in Visual Studio 2022.
For changes in earlier versions of Visual Studio:
| 2019 | C++ conformance improvements in Visual Studio 2019 |
| 2017 | C++ conformance improvements in Visual Studio 2017 |
| 2003-2015 | Visual C++ What's New 2003 through 2015 |
Visual Studio 2022 version 17.14 includes the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
Fixed errant compiler errors when using <format> in a CUDA project.
Fixed a compiler issue where the address of a local variable could "leak" during constexpr evaluation. For example:
const unsigned & func() { const int x = 0; constexpr const unsigned & r1 = x; // Previously accepted, now an error return r1; } auto r = func(); // Previously, the local address leakedExample #2
#include <initializer_list> void test() { constexpr std::initializer_list<int> xs { 1, 2, 3 }; // Previously accepted, now an error static constexpr std::initializer_list<int> ys { 1, 2, 3 }; // Correct usage - note use of static }Code compiled with /permissive- no longer accepts a combination of friend and static on a declaration. The fix is usually to remove static from the declaration. For example:
struct S { friend static void f(); // Previously accepted, now emits error C2440: 'static' cannot be used with 'friend' };Reference binding to volatile-qualified types fixed when referring to a base or derived class. For example:
struct A {}; struct B : public A {}; void f(A&); // 1 void f(const volatile A&); // 2 f(B{}); // Previously called 2. This is ill-formed under /permissive- or /Zc:referenceBinding. Chooses 1 if relaxed reference binding rules are enabled.For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes, and performance improvements, see STL Changelog VS 2022 17.14.
Visual Studio 2022 version 17.13 includes the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes, and performance improvements, see STL Changelog VS 2022 17.13.
Language constructs such as range-for and structured bindings have special argument-dependent lookup rules for certain identifiers such as begin, end, or get. Previously, this lookup included candidates from the std namespace, even when namespace std isn't part of the ordinary set of associated namespaces for argument-dependent lookup.
Programs that introduced declarations to std for these constructs no longer compile. Instead, the declarations should be in a normal associated namespace for the types involved (possibly including the global namespace).
template <typename T> struct Foo {}; namespace std { // To correct the program, move these declarations from std to the global namespace template <typename T> T* begin(Foo<T>& f); template <typename T> T* end(Foo<T>& f); } void f(Foo<int> foo) { for (auto x : foo) // Previously compiled. Now emits error C3312: no callable 'begin' function found for type 'Foo<int>' { ... } }Previously, the compiler permitted changing or undefining certain implementation-provided macros such as _MSC_EXTENSIONS. Altering the definition of certain macros can result in undefined behavior.
Attempting to alter or undefine certain reserved macro names now results in the level-1 warning C5308. In /permissive- mode, this warning is treated as an error.
#undef _MSC_EXTENSIONS // Warning C5308: Modifying reserved macro name `_MSC_EXTENSIONS` may cause undefined behaviorVisual Studio 2022 version 17.12 includes the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes, and performance improvements, see STL Changelog VS 2022 17.12.
This is a source/binary breaking change.
The implicit conversion to bool from _com_ptr_t instances can be surprising or lead to compiler errors. C.164: Avoid implicit conversion operators in the C++ Core Guidelines discourage implicit conversion functions. And _com_ptr_t contained implicit conversions to both bool and Interface*. These two implicit conversions can lead to ambiguities.
To address this, the conversion to bool is now explicit. The conversion to Interface* is unchanged.
A macro is provided to opt-out of this new behavior and restore the previous implicit conversion. Compile with /D_COM_DISABLE_EXPLICIT_OPERATOR_BOOL to opt-out of this change. We recommend that you modify the code to not rely on implicit conversions.
For example:
#include <comip.h> template<class Iface> using _com_ptr = _com_ptr_t<_com_IIID<Iface, &__uuidof(Iface)>>; int main() { _com_ptr<IUnknown> unk; if (unk) // Still valid { // ... } bool b = unk; // Still valid. int v = unk; // Previously permitted, now emits C2240: cannot convert from '_com_ptr_t<_com_IIID<IUnknown,& _GUID_00000000_0000_0000_c000_000000000046>>' to 'int' }This is a source/binary breaking change.
A constant expression was always noexcept, even if it involved a function call to a function declared with a potentially throwing exception specification. This wording was removed in C++17, although the Microsoft Visual C++ compiler still supported it in /permissive mode in all C++ language versions.
This /permissive mode behavior is removed. Constant expressions are no longer given special implicit behavior.
The noexcept specifier on constexpr functions is now respected in all modes. This change is required for correct implementation of later core issue resolutions that rely on the standard noexcept behavior.
For example:
constexpr int f(bool b) noexcept(false) { if (b) { throw 1; } else { return 1; } } void g(bool b) { noexcept(f(b)); // false. No change to behavior noexcept(f(true)); // false. No change to behavior noexcept(f(false)); // false. Was true in /permissive mode only in previous versions. }Visual Studio 2022 version 17.11 includes the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes, and performance improvements, see STL Changelog VS 2022 17.11.
Per P3142R0, it's now easy to generate a blank line with println. This feature is available when compiling with /std:c++latest. Before this change, you wrote: println(""); Now you write: println();.
Per P2286R8, range_formatter is now implemented. This feature is available when compiling with /std:c++latest.
Visual Studio 2022 version 17.10 includes the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes, and performance improvements, see STL Changelog VS 2022 17.10.
The compiler used to specialize conversion operators incorrectly in some cases, which could lead to a mismatched return type. These invalid specializations no longer happen. This is a source code breaking change.
// Example 1 struct S { template<typename T> operator const T*(); }; void test() { S{}.operator int*(); // this is invalid now S{}.operator const int*(); // this is valid } // Example 2 // In some cases, the overload resolution result may change struct S { template <typename T> operator T*(); // overload 1 template <typename T> operator const T*(); // overload 2 }; void test() { S{}.operator int*(); // this used to call overload 2, now it calls overload 1 }Support added for WG21 P2334R1 (C++23) and WG14 N2645 (C++23) which introduced the #elifdef and #elifndef preprocessor directives. Requires /std:clatest or /std:c++latest.
Before:
#ifdef __cplusplus #include <atomic> #elif !defined(__STDC_NO_ATOMICS__) #include <stdatomic.h> #else #include <custom_atomics_library.h> #endifAfter:
#ifdef __cplusplus #include <atomic> #elifndef __STDC_NO_ATOMICS__ #include <stdatomic.h> #else #include <custom_atomics_library.h> #endifApplies to the C language (C17 and later). Also added to Microsoft Visual Studio 17.9
In versions of Visual C++ before Visual Studio 2022 version 17.9, if the _Alignas specifier appeared next to a structured type in a declaration, it wasn't applied correctly according to the ISO-C Standard.
// 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");According to the ISO-C Standard, this code should compile without static_assert emitting a diagnostic.
The _Alignas directive applies only to the member variable member1. It must not change the alignment of struct Inner. However, before Visual Studio 17.9.1, the diagnostic "incorrect alignment" was emitted. The compiler aligned member2 to an offset of 32 bytes within the struct Outer type.
This is a binary breaking change, so a warning is now emitted when this change takes effect. Warning C5274 is now emitted at warning level 1 for the previous example: warning C5274: behavior change: _Alignas no longer applies to the type 'Inner' (only applies to declared data objects).
Also, in previous versions of Visual Studio, when the _Alignas specifier appeared next to an anonymous type declaration, it was ignored.
// 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");Previously, both static_assert statements failed when compiling this code. Now the code compiles, but emits the following level 1 warnings:
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)To get the previous behavior, replace _Alignas(N) with __declspec(align(N)). Unlike _Alignas, declspec(align) applies to the type.
This is a source code breaking change. Previously, the compiler didn't detect the convention of wrapping an assignment in parentheses, if assignment was intended, to suppress warning C4706 about assignment within a conditional expression. The compiler now detects the parentheses and suppresses the warning.
#pragma warning(error: 4706) struct S { auto mf() { if (value = 9) return value + 4; else return value; } int value = 9; };The compiler now also emits the warning in cases where the function isn't referenced. Previously, because mf is an inline function that isn't referenced, warning C4706 wasn't emitted for this code. Now the warning is emitted:
error C4706: assignment used as a condition note: if an assignment is intended you can enclose it in parentheses, '(e1 = e2)', to silence this warningTo fix this warning, either use an equality operator, value == 9, if this is what was intended. Or, wrap the assignment in parentheses, (value = 9), if assignment is intended. Otherwise, since the function is unreferenced, remove it.
Visual Studio 2022 version 17.9 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
For a broader summary of changes made to the Standard Template Library, see STL Changelog VS 2022 17.9.
In versions of Visual C++ before Visual Studio 2022 version 17.9, when _Alignas appeared next to a structure type in a declaration, it wasn't applied correctly according to the ISO-C Standard. For example:
// 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");According to the ISO-C Standard, this code should compile without the static_assert emitting a diagnostic. The _Alignas directive applies only to the member variable member1. It must not change the alignment of struct Inner. However, before release 17.9.1 of Visual Studio, the diagnostic "incorrect alignment" was emitted. The compiler aligned member2 to a 32 byte offset within struct Outer.
Fixing this is a binary breaking change, so when this change in behavior is applied a warning is emitted. For the preceding code, Warning C5274, "_Alignas no longer applies to the type 'Inner' (only applies to declared data objects)" is now emitted at warning level 1.
In previous versions of Visual Studio, _Alignas was ignored when it appeared next to an anonymous type declaration. For example:
// 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");Previously, both static_assert statements failed when compiling this code. The code now compiles, but with the following level 1 warnings:
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)If you want the earlier behavior, replace _Alignas(N) with __declspec(align(N)). Unlike _Alignas, declspec(align) can be applied to a type.
__VA_OPT__ was added to C++20 and C23. Previous to its addition, there wasn't a standard way to elide a comma in a variadic macro. To provide better backward compatibility, __VA_OPT__ is enabled under the token based preprocessor /Zc:preprocessor across all language versions.
For example, this now compiles without 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")For C23, the following are available when using the /std:clatest compiler switch:
The following are available for all C language versions:
C++23 features
Visual Studio 2022 version 17.8 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
The C compiler used to accept the /FU option, even though it hasn't support managed compilation for some time. It now issues an error. Projects that pass this option need to restrict it to C++/CLI projects only.
The C++23 named modules std and std.compat are now available when compiling with /std:c++20.
For a broader summary of changes made to the C++ Standard Library, see STL Changelog VS 2022 17.8.
Visual Studio 2022 version 17.7 contains the following highlighted conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
This switch behaves like the /std:c++latest switch for the C++ compiler. The switch enables all currently implemented compiler and standard library features proposed for the next draft C standard, as well as some in-progress and experimental features.
The <print> library is now supported. See P2093R14 Formatted output.
Implemented views::cartesian_product.
For a broader summary of changes made to the Standard Template Library, see STL Changelog VS 2022 17.7.
Previously, the using directive could cause names from used namespaces to remain visible when they shouldn't. This could cause unqualified name lookup to find a name in a namespace even when there's no using directive active.
Here are some examples of the new and old behavior.
References in the following comments to "(1)" mean the call to f<K>(t) in namespace A:
The same underlying issue can cause code that previously compiled to now be rejected:
#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; }Visual Studio 2022 version 17.6 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
C++20 deprecated applying certain operators to types qualified with volatile. For example, when the following code is compiled with cl /std:c++20 /Wall test.cpp:
void f(volatile int& expr) { ++expr; }The compiler produces test.cpp(3): warning C5214: applying '++' to an operand with a volatile qualified type is deprecated in C++20.
In C++20, compound assignment operators (operators of the form @=) were deprecated. In C++23, compound operators excluded in C++20 are no longer deprecated. For example, in C++23 the following code doesn't produce a warning, whereas it does in C++20:
void f(volatile int& e1, int e2) { e1 += e2; }For more information about this change, see CWG:2654
In C++20, P2468R2 changed the compiler to accept code such as:
struct S { bool operator==(const S&); bool operator!=(const S&); }; bool b = S{} != S{};The compiler accepts this code, which means that the compiler is more strict with code such as:
struct S { operator bool() const; bool operator==(const S&); }; bool b = S{} == S{};Version 17.5 of the compiler accepts this program. Version 17.6 of the compiler rejects it. To fix it, add const to operator== to remove the ambiguity. Or, add a corresponding operator!= to the definition as shown in the following example:
struct S { operator bool() const; bool operator==(const S&); bool operator!=(const S&); }; bool b = S{} == S{};Microsoft C/C++ compiler versions 17.5 and 17.6 accept the previous program, and calls S::operator== in both versions.
The general programming model outlined in P2468R2 is that if there's a corresponding operator!= for a type, it typically suppresses the rewrite behavior. Adding a corresponding operator!= is the suggested fix for code that previously compiled in C++17. For more information, see Programming Model.
Visual Studio 2022 version 17.4 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
In versions of Visual Studio before Visual Studio 2022 version 17.4, the C++ compiler didn't correctly determine the underlying type of an unscoped enumeration with no fixed base type. Under /Zc:enumTypes, we now correctly implement the standard behavior.
The C++ Standard requires the underlying type of an enum to be large enough to hold all enumerators in that enum. Sufficiently large enumerators can set the underlying type of the enum to unsigned int, long long, or unsigned long long. Previously, such enum types always had an underlying type of int in the Microsoft compiler, regardless of enumerator values.
When enabled, the /Zc:enumTypes option is a potential source and binary breaking change. It's off by default, and not enabled by /permissive-, because the fix might affect binary compatibility. Some enumeration types change size when the conformant fix is enabled. Certain Windows SDK headers include such enumeration definitions.
In versions of Visual Studio before Visual Studio 2022 version 17.4, the C++ compiler didn't correctly model the types of enumerators. It could assume an incorrect type in enumerations without a fixed underlying type before the closing brace of the enumeration. Under /Zc:enumTypes, the compiler now correctly implements the standard behavior.
The C++ Standard specifies that within an enumeration definition of no fixed underlying type, initializers determine the types of enumerators. Or, for the enumerators with no initializer, by the type of the previous enumerator (accounting for overflow). Previously, such enumerators were always given the deduced type of the enumeration, with a placeholder for the underlying type (typically int).
When enabled, the /Zc:enumTypes option is a potential source and binary breaking change. It's off by default, and not enabled by /permissive-, because the fix might affect binary compatibility. Some enumeration types change size when the conformant fix is enabled. Certain Windows SDK headers include such enumeration definitions.
In this example the enumerator A should have type char before the closing brace of the enumeration, so B should be initialized using sizeof(char). Before the /Zc:enumTypes fix, A had enumeration type Enum with a deduced underlying type int, and B was initialized using sizeof(Enum), or 4.
Visual Studio 2022 version 17.3 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
The C compiler didn't properly compare modifiers between pointers, especially void*. This defect could result in an improper diagnosis of incompatibility between const int** and void* and compatibility between int* volatile* and void*.
Visual Studio 2022 version 17.2 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
Visual Studio 2022 version 17.2 adds level 3 warning C5255 for unterminated Unicode bidirectional characters in comments and strings. The warning addresses a security concern described in Trojan Source: Invisible Vulnerabilities by Nicholas Boucher and Ross Anderson. For more information on Unicode bidirectional characters, see Unicode® Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM.
Warning C5255 only addresses files that, after conversion, contain Unicode bidirectional characters. This warning applies to UTF-8, UTF-16, and UTF-32 files, so the proper source-encoding must be provided. This change is a source breaking change.
In versions of Visual Studio before Visual Studio 2022 version 17.2, an unterminated bidirectional character didn't produce a warning. Visual Studio 2022 version 17.2 produces warning 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' */Visual Studio 2022 version 17.2 fixes a bug in <charconv> from_chars() float tiebreaker rules that produced incorrect results. This bug affected decimal strings that were at the exact midpoint of consecutive float values, within a narrow range. (The smallest and largest affected values were 32768.009765625 and 131071.98828125, respectively.) The tiebreaker rule wanted to round to "even," and "even" happened to be "down," but the implementation incorrectly rounded "up" (double was unaffected.) For more information and implementation details, see microsoft/STL#2366.
This change affects runtime behavior in the specified range of cases:
In versions before 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.In Visual Studio 2022 version 17.2 and after:
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.The C standard requires that a conforming C implementation defines __STDC__ as 1. Due to the behavior of the UCRT, which doesn't expose POSIX functions when __STDC__ is 1, it isn't possible to define this macro for C by default without introducing breaking changes to the stable language versions. Visual Studio 2022 version 17.2 and later add a conformance option /Zc:__STDC__ that defines this macro. There's no negative version of the option. Currently, we plan to use this option by default for future versions of C.
This change is a source breaking change. It applies when C11 or C17 mode is enabled (/std:c11 or /std:c17) and /Zc:__STDC__ is specified.
Warning C5246 reports missing braces during aggregate initialization of a subobject. Before Visual Studio 2022 version 17.2, the warning didn't handle the case of an anonymous struct or union.
This change is a source breaking change. It applies when the off-by-default warning C5246 is enabled.
In Visual Studio 2022 version 17.2 and later, this code now causes an 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 */To resolve this issue, add braces to the initializer:
void f() { S s = { { 1.0f, 2.0f, 3.14f, 4.0f } }; }Visual Studio 2022 version 17.1 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
The C++ Standard only allows a lambda expression in block scope to have a capture-default. In Visual Studio 2022 version 17.1 and later, the compiler detects when a capture default isn't allowed in a nonlocal lambda expression. It emits a new level 4 warning, C5253.
This change is a source breaking change. It applies in any mode that uses the new lambda processor: /Zc:lambda, /std:c++20, or /std:c++latest.
In Visual Studio 2022 version 17.1 this code now emits an 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; }; // ^To fix this issue, remove the capture default:
#pragma warning(error:5253) auto incr = [](int value) { return value + 1; };Before Visual Studio 2022 version 17.1, the compiler reported an incorrect error message on certain pointer-to-function comparisons in C code. The incorrect message was reported when you compared two function pointers that had the same argument counts but incompatible types. Now, we issue a different warning that complains about pointer-to-function incompatibility rather than function parameter mismatch.
This change is a source breaking change. It applies when code is compiled as C.
In Visual Studio 2022 version 17.1 and later, if the expression associated with a static_assert isn't a dependent expression, the compiler evaluates the expression when it's parsed. If the expression evaluates to false, the compiler emits an error. Previously, if the static_assert was within the body of a function template (or within the body of a member function of a class template), the compiler wouldn't perform this analysis.
This change is a source breaking change. It applies in any mode that implies /permissive- or /Zc:static_assert. This change in behavior can be disabled by using the /Zc:static_assert- compiler option.
In Visual Studio 2022 version 17.1 and later, this code now causes an error:
template<typename T> void f() { static_assert(false, "BOOM!"); }To fix this issue, make the expression dependent. For example:
template<typename> constexpr bool dependent_false = false; template<typename T> void f() { static_assert(dependent_false<T>, "BOOM!"); }With this change, the compiler only emits an error if the function template f is instantiated.
Visual Studio 2022 version 17.0 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
When you declare an instance of an enumeration type as a bitfield, the width of the bitfield must accommodate all possible values of the enumeration. Otherwise, the compiler issues a diagnostic message. Consider this example: Consider:
enum class E : unsigned { Zero, One, Two }; struct S { E e : 1; };A programmer might expect the class member S::e can hold any of the explicitly named enum values. Given the number of enumeration elements, it isn't possible. The bitfield can't cover the range of explicitly provided values of E (conceptually, the domain of E). To address the concern that the bitfield width isn't large enough for the domain of the enumeration, a new (off by default) warning is added to 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 }; ^This compiler behavior is a source and binary breaking change that affects all /std and /permissive modes.
The C++ Standard inadvertently allowed an ordered pointer comparison against nullptr or 0. For example:
bool f(int *p) { return p >= 0; }WG21 paper N3478 removed this oversight. This change is implemented in MSVC. When the example is compiled by using /permissive- (and /diagnostics:caret), it emits the following error:
t.cpp(3,14): error C7664: '>=': ordered comparison of pointer and integer zero ('int *' and 'int') return p >= 0; ^This compiler behavior is a source and binary breaking change that affects code compiled using /permissive- in all /std modes.
Was this page helpful?
Was this page helpful?
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?