Visual Studio 2022 での C++ 準拠の強化、動作変更、バグ修正

Visual Studio の Microsoft C/C++ (MSVC) では、リリースごとに準拠の強化とバグ修正が行われます。 この記事では、大幅な機能強化の一覧を、メジャー リリースごとおよびバージョンごとに示します。 特定のバージョンの変更に直接移動するには、この記事のリンクを使用します

このドキュメントには、Visual Studio 2022 での変更点が記載されています。

Visual Studio 2019 の変更点については、Visual Studio 2019 での C++ 準拠の機能強化に関するページを参照してください
Visual Studio 2017 での変更点については、Visual Studio 2017 での C++ 準拠の強化に関する記事を参照してください。
以前のバージョンでの変更については、「Visual C++ What's New 2003 to 2015」を参照してください

Visual Studio 2022 バージョン 17.9 の準拠の機能強化

Visual Studio 2022 バージョン 17.9 には、Microsoft C/C++ コンパイラでの次の準拠の機能強化、バグ修正、および動作の変更が含まれています。

標準テンプレート ライブラリに加えられた変更のより広範な概要については、STL Changelog VS 2022 17.9 を参照してください

C の _Alignas 構造化型への適用

Visual Studio 2022 バージョン 17.9 より前のバージョンの Visual C++ では、宣言の構造体型の横に表示された場合 _Alignas 、ISO-C 標準に従って正しく適用されませんでした。 次に例を示します。

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

ISO-C 標準によると、このコードは診断を static_assert 出力せずにコンパイルする必要があります。 ディレクティブは _Alignas メンバー変数 member1にのみ適用されます。 の配置 struct Innerを変更しないでください。 ただし、Visual Studio のリリース 17.9.1 より前は、診断 "正しくないアラインメント" が出力されていました。 内の 32 バイト オフセットstruct Outerにアラインされたmember2コンパイラ。

この修正はバイナリ破壊的変更であるため、この動作の変更が適用されると警告が生成されます。 前のコードの警告 C5274 では、"_Alignas Inner' 型に適用されなくなりました (宣言されたデータ オブジェクトにのみ適用されます)" が警告レベル 1 で出力されるようになりました。

以前のバージョンの Visual Studio では、 _Alignas 匿名型宣言の横に表示されたときに無視されていました。 次に例を示します。

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

以前は、このコードをコンパイルするときに両方 static_assert のステートメントが失敗しました。 コードはコンパイルされるようになりましたが、次のレベル 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)

以前の動作が必要な場合は、次のように__declspec(align(N))置き換えます_Alignas(N)。 とは異なり _Alignasdeclspec(align) 型に適用できます。

__VA_OPT__ は、次の下の拡張機能として有効になっています。 /Zc:preprocessor

__VA_OPT__ が C++20 および C23 に追加されました。 追加する前は、可変数マクロでコンマを引き出す標準的な方法はありませんでした。 下位互換性を向上させるために、 __VA_OPT__ すべての言語バージョンでトークン ベースのプリプロセッサ /Zc:preprocessor の下で有効にします。

たとえば、これはエラーなしでコンパイルされるようになりました。

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

C23 言語

C23 の場合、コンパイラ スイッチを使用する場合は、次の情報を /std:clatest 使用できます。

typeof
typeof_unqual

すべての C 言語バージョンで使用できる言語は次のとおりです。

__typeof__
__typeof_unqual__

C++ 標準ライブラリ

C++23 の機能

Visual Studio 2022 バージョン 17.8 での準拠の機能強化

Visual Studio 2022 バージョン 17.8 には、Microsoft C/C++ コンパイラでの次の準拠の機能強化、バグ修正、および動作の変更が含まれています。

/FU でエラーが発生する

C コンパイラは、しばらくの間マネージド コンパイルをサポートしていないにもかかわらず、 /FU オプションを受け入れていました。 エラーが発生するようになりました。 このオプションを渡すプロジェクトでは、C++/CLI プロジェクトのみに制限する必要があります。

C++ 標準ライブラリ

/std:c++20 を使用してコンパイルするときに、C++23 の名前付きモジュール stdstd.compat を使用できるようになりました。

C++ Standard ライブラリに加えられた変更のより広範な概要については、STL Changelog VS 2022 17.8 を参照してください。

Visual Studio 2022 バージョン 17.7 の準拠の機能強化

Visual Studio 2022 バージョン 17.7 には、Microsoft C/C++ コンパイラでの次の強調表示された準拠の機能強化、バグ修正、および動作の変更が含まれています。

/std:clatest を C コンパイラに追加しました

このスイッチは、C++ コンパイラの /std:c++latest スイッチと同様に動作します。 このスイッチを使用すると、次のドラフト C 標準に対して提案されている現在実装されているコンパイラと標準ライブラリの機能のほか、進行中の機能と試験的な機能の一部が有効になります。

C++ 標準ライブラリ

<print> ライブラリがサポートされるようになりました。 「P2093R14 書式設定された出力」を参照してください。

views::cartesian_product が実装されています。

標準テンプレート ライブラリ に加えられた変更の概要については、STL Changelog VS 2022 17.7 を参照してください。

using 準拠

以前は、using ディレクティブを使用すると、使用されている名前空間の名前が表示されるべきでない場合でも、表示されたままになる可能性があります。 これにより、using ディレクティブがアクティブでない場合でも、非修飾名検索によって名前空間内の名前の検索が発生する可能性があります。

新旧の動作の例をいくつか次に示します。
次のコメントの "(1)" への参照は、名前空間 A 内の f<K>(t) の呼び出しを意味します:

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

同じ根本的な問題により、以前にコンパイルされたコードが拒否される可能性があります:

#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 バージョン 17.6 の準拠の機能強化

Visual Studio 2022 バージョン 17.6 には、Microsoft C/C++ コンパイラでの次の準拠の機能強化、バグ修正、および動作の変更が含まれています。

複合 volatile 代入は非推奨になりました

C++20 では、volatile で修飾された型に特定の演算子を適用することが非推奨になりました。 たとえば、次のコードを cl /std:c++20 /Wall test.cpp でコンパイルする場合です。

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

コンパイラによって test.cpp(3): warning C5214: applying '++' to an operand with a volatile qualified type is deprecated in C++20 が生成されます。

C++20 では、複合代入演算子 (@= 形式の演算子) は非推奨になりました。 C++23 では、C++20 で除外された複合演算子は非推奨になりました。 たとえば、C++23 では次のコードで警告は生成されませんが、C++20 では生成されます。

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

この変更の詳細については、CWG:2654 を参照してください

式の等価性の書き換えは破壊的変更ではない (P2468R2)

C++20 では、P2468R2 でコンパイラが次のようなコードを受け入れるように変更されました。

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

コンパイラはこのコードを受け入れます。つまり、コンパイラは次のようなコードに対してより厳密になります。

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

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

バージョン 17.5 のコンパイラはこのプログラムを受け入れます。 バージョン 17.6 のコンパイラはそれを拒否します。 これを修正するには、operator==const を追加してあいまいさを解消します。 または、次の例に示すように、対応する operator!= を定義に追加します。

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

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

Microsoft C/C++ コンパイラ バージョン 17.5 および 17.6 は、前のプログラムを受け入れ、両方のバージョンで S::operator== を呼び出します。

P2468R2 で概説されている一般的なプログラミング モデルでは、型に対応する operator!= がある場合、通常は書き換え動作を抑制します。 対応する operator!= の追加は、C++17 で以前にコンパイルされたコードに推奨される修正です。 詳細については、「プログラミング モデル」を参照してください。

Visual Studio 2022 バージョン 17.4 の準拠の強化

Visual Studio 2022 バージョン 17.4 の Microsoft C/C++ コンパイラには、以下の準拠の強化、バグ修正、動作変更が含まれています。

固定の型がないスコープを持たない enum の基となる型

Visual Studio 2022 バージョン 17.4 より前のバージョンの Visual Studio に含まれる C++ コンパイラでは、固定の基本データ型がない、スコープを持たない列挙型の基となる型が正しく判断されませんでした。 現在、/Zc:enumTypes では、標準の動作が正しく実装されるようになりました。

C++ 標準では、enum の基となる型は、その enum 内のすべての列挙子を保持できる十分な大きさである必要があります。 十分に大きな列挙子は、enum の基となる型を unsigned intlong long、または unsigned long long に設定できます。 以前は、列挙子の値に関係なく、このような enum 型は Microsoft コンパイラで常に int の基となる型を持っていました。

有効にした場合、/Zc:enumTypes オプションはソースとバイナリの破壊的変更になる可能性があります。 この修正プログラムはバイナリの互換性に影響を与える可能性があるため、既定ではオフであり、 /permissive- では有効になっていません。 準拠する修正プログラムが有効になった場合、一部の列挙型はサイズが変更されます。 特定の Windows SDK ヘッダーには、このような列挙型の定義が含まれています。

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

固定の基となる型がない enum 定義内の列挙子の型

Visual Studio 2022 バージョン 17.4 より前のバージョンの Visual Studio に含まれる C++ コンパイラでは、列挙子の型が正しくモデル化されませんでした。 列挙型の右中かっこの前に固定の基となる型がない場合、列挙型で不適切な型が想定される可能性がありました。 /Zc:enumTypes のコンパイラでは、標準の動作が正しく実装されるようになりました。

C++ 標準では、固定の基になる型のない列挙型定義内で、初期化子によって列挙子の型が決定されることが示されています。 または、初期化子のない列挙子の場合は、(オーバーフローを考慮して) 直前の列挙子の型によって決定されます。 以前は、このような列挙子には、基となる型のプレースホルダー (通常は int) と共に、列挙型の推定型が常に指定されていました。

有効にした場合、/Zc:enumTypes オプションはソースとバイナリの破壊的変更になる可能性があります。 この修正プログラムはバイナリの互換性に影響を与える可能性があるため、既定ではオフであり、 /permissive- では有効になっていません。 準拠する修正プログラムが有効になった場合、一部の列挙型はサイズが変更されます。 特定の Windows SDK ヘッダーには、このような列挙型の定義が含まれています。

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

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

この例では、列挙子は列挙型 A の右中かっこの前に型 char を持つ必要があるため B 、を使用して sizeof(char)初期化する必要があります。 /Zc:enumTypes の修正前は、A は列挙型 Enum であり、推論される基となる型は int でした。Bsizeof(Enum) (つまり 4) を使って初期化されていました。

Visual Studio 2022 バージョン 17.3 の準拠の強化

Visual Studio 2022 バージョン 17.3 の Microsoft C/C++ コンパイラには、以下の準拠の強化、バグ修正、動作変更が含まれています。

C: ポインター間の修飾子互換性チェックの強化

C コンパイラでは、ポインタ間の修飾子 (特に void*) が適切に比較されていませんでした。 この欠陥により、const int**void* の間の非互換性および int* volatile*void* の間の互換性の診断が適切に行われない可能性がありました。

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
}

Visual Studio 2022 バージョン 17.2 の準拠の強化

Visual Studio 2022 バージョン 17.2 の Microsoft C/C++ コンパイラには、以下の準拠の強化、バグ修正、動作変更が含まれています。

未終了の双方向文字の警告

Visual Studio 2022 バージョン 17.2 では、コメントと文字列での未終了の Unicode 双方向文字に対してレベル 3 の警告 C5255 が追加されます。 この警告は、Nicholas Boucher 氏と Ross Anderson 氏による「Trojan Source: Invisible Vulnerabilities (トロイの木馬のソース: 目に見えない脆弱性)」で説明されているセキュリティ上の懸念に対処するものです。 Unicode 双方向文字の詳細については、「Unicode® Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM (Unicode® 標準の付属書 #9: Unicode 双方向アルゴリズム)」を参照してください。

警告 C5255 で対処されるのは、変換後に Unicode 双方向文字を含むファイルのみです。 この警告は UTF-8、UTF-16、UTF-32 ファイルに適用されるため、適切なソース エンコードを指定する必要があります。 この変更は、ソースの破壊的変更です。

例 (前と後)

Visual Studio 2022 バージョン 17.2 より前のバージョンの Visual Studio では、未終了の双方向文字によって警告が生成されませんでした。 Visual Studio 2022 バージョン 17.2 では、警告 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 タイブレーカー

Visual Studio 2022 バージョン 17.2 では、間違った結果を生成する <charconv>from_chars()float タイブレーカー ルールのバグが修正されています。 このバグは、狭い範囲内で、連続する float 値の厳密な中間点にある 10 進数値文字列に影響を与えました。 (影響を受ける値の最小値と最大値はそれぞれ、および131071.98828125、それぞれでした32768.009765625)。タイブレーカールールは "偶数" に丸めたいと考えていましたが、"偶数" は "ダウン" でしたが、実装は誤って "切り上げ" (double影響を受けませんでした)。)詳細と実装の詳細については、microsoft/STL#2366 を参照してください

この変更は、指定されたケース範囲でのランタイム動作に影響します:

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

Visual Studio 2022 バージョン 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.

Visual Studio 2022 バージョン 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.0078125
This rounded DOWN.

/Zc:__STDC__ で C の __STDC__ が利用可能に

C 標準では、準拠する C 実装では __STDC__1 と定義されている必要があります。 __STDC__1 のときは POSIX 関数が公開されない UCRT の動作により、安定した言語バージョンに破壊的変更を加えることなく、既定で C 用にこのマクロを定義することはできません。 Visual Studio 2022 バージョン 17.2 以降では、このマクロを定義する準拠オプション /Zc:__STDC__ が追加されます。 このオプションの負のバージョンはありません。 現在、C の今後のバージョンでは、既定でこのオプションが使用される予定です。

この変更は、ソースの破壊的変更です。 /Zc:__STDC__ と共に、C11 または C17 モード (/std:c11 または /std:c17) が有効になっている場合に適用されます。

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

*/

中かっこの不足に対する警告

警告 C5246 では、サブオブジェクトの集約の初期化中に不足している中かっこが報告されます。 Visual Studio 2022 バージョン 17.2 より前では、この警告により匿名の struct または union のケースは処理されませんでした。

この変更は、ソースの破壊的変更です。 既定で無効の警告 C5246 が有効になっている場合に適用されます。

Visual Studio 2022 バージョン 17.2 以降では、次のコードによってエラーが発生します。

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

この問題を解決するには、初期化子に中かっこを追加します。

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

Visual Studio 2022 バージョン 17.1 の準拠の強化

Visual Studio 2022 バージョン 17.1 の Microsoft C/C++ コンパイラには、以下の準拠の強化、バグ修正、動作変更が含まれています。

ローカル以外のラムダ式で不適切な形式のキャプチャの既定値を検出する

C++ 標準では、ブロック スコープ内のラムダ式でキャプチャの既定値のみが許可されます。 Visual Studio 2022 バージョン 17.1 以降では、ローカル以外のラムダ式でキャプチャの既定値が許可されていない場合にコンパイラによって検出されます。 新しいレベル 4 の警告 C5253 が出力されます。

この変更は、ソースの破壊的変更です。 これは、新しいラムダ プロセッサ (/Zc:lambda/std:c++20、または /std:c++latest) を使用する任意のモードで適用されます。

Visual Studio 2022 バージョン 17.1 では、次のコードでエラーが生成されるようになりました。

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

この問題を解決するには、キャプチャの既定値を削除します。

#pragma warning(error:5253)

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

関数からポインターへの操作に対する C4028 が C4133 に

Visual Studio 2022 バージョン 17.1 より前では、C コードにおける特定の関数からポインターへの比較で、コンパイラから正しくないエラー メッセージが報告されました。 引数の数は同じでも型に互換性のない 2 つの関数ポインターを比較すると、正しくないメッセージが報告されました。 今回、関数パラメーターの不一致ではなく、関数へのポインターの非互換性を示す別の警告が発行されるようになりました。

この変更は、ソースの破壊的変更です。 これは、コードが C としてコンパイルされる場合に適用されます。

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

非依存の static_assert でのエラー

Visual Studio 2022 バージョン 17.1 以降では、a に関連付 static_assert けられている式が依存式でない場合、コンパイラは解析時に式を評価します。 式が false に評価された場合、コンパイラはエラーを出力します。 以前は、static_assert が関数テンプレートの本文内 (またはクラス テンプレートのメンバー関数の本文内) に含まれている場合、コンパイラではこの分析が実行されませんでした。

この変更は、ソースの破壊的変更です。 これは、/permissive- または /Zc:static_assert を暗黙的に指定するすべてのモードで適用されます。 この動作変更は、/Zc:static_assert- コンパイラ オプションを使って無効にすることができます。

Visual Studio 2022 バージョン 17.1 以降では、次のコードによってエラーが発生します。

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

この問題を解決するには、式を依存させる必要があります。 次に例を示します。

template<typename>
constexpr bool dependent_false = false;

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

この変更により、関数テンプレート f がインスタンス化された場合にのみ、コンパイラによってエラーが出力されます。

Visual Studio 2022 バージョン 17.0 の準拠の強化

Visual Studio 2022 バージョン 17.0 の Microsoft C/C++ コンパイラには、以下の準拠の強化、バグ修正、動作変更が含まれています。

列挙型のビットフィールド幅に関する警告

列挙型のインスタンスをビットフィールドとして宣言する場合、ビットフィールドの幅が列挙型に使用できるすべての値に対応する必要があります。 そうでない場合、コンパイラによって診断メッセージが発行されます。 たとえば、次の例について考えてみましょう。

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

struct S {
  E e : 1;
};

プログラマが、クラス メンバー S::e を使うことで、明示的に名前を付けた enum 値を保持できると考える可能性があります。 列挙要素の数を考えると、これは不可能です。 ビットフィールドで、E の明示的に提供された値 (概念的には E の "ドメイン") の範囲をカバーすることはできません。 ビットフィールドの幅が列挙型のドメインに対して十分に大きくないという懸念に対処するために、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 };
                                     ^

コンパイラのこの動作はソースおよびバイナリの破壊的変更であり、すべての /std および /permissive モードに影響します。

nullptr または 0 に対する順序付きポインター比較のエラー

C++ 標準では、nullptr または 0 に対する順序付きポインター比較が誤って許可されました。 次に例を示します。

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

WG21 文書 N3478 で、この見落としが削除されました。 この変更は MSVC で実装されます。 この例を /permissive- (および /diagnostics:caret ) を使用してコンパイルすると、次のエラーが出力されます。

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

コンパイラのこの動作はソースおよびバイナリの破壊的変更であり、すべての /std モードで /permissive- を使用してコンパイルされたコードに影響します。

関連項目

Microsoft C/C++ 言語の準拠