/Zc:enumTypes
(列挙型の推論を有効にする)
/Zc:enumTypes
コンパイラ オプションを使用すると、基になる型と列挙子の型推論enum
C++ に準拠できます。
構文
/Zc:enumTypes
[-
]
解説
/Zc:enumTypes
コンパイラ オプションは、列挙型の基本型と列挙子の型を推論するための標準 C++ 準拠動作を実装します。
/Zc:enumTypes
オプションは、Visual Studio 2022 バージョン 17.4 の新機能です。 このオプションは既定ではオフになっており、 /permissive-
では有効になっていません。 このオプションを明示的に無効にするには、 /Zc:enumTypes-
を使用します。
有効にした場合、/Zc:enumTypes
オプションはソースとバイナリの破壊的変更になる可能性があります。 一部の列挙型は、準拠 /Zc:enumTypes
オプションが有効になっているとサイズが変更されます。 特定の Windows SDK ヘッダーには、このような列挙型の定義が含まれています。
C++ 標準では、列挙型の基になる型が、その中で宣言されているすべての列挙子を保持するのに十分な大きさである必要があります。 十分に大きな列挙子は、enum
の基となる型を unsigned int
、long long
、または unsigned long long
に設定できます。 以前は、このような列挙型には、列挙子の値に関係なく、常に基になる型の int
が Microsoft コンパイラに含まれていました。
また、C++ 標準では、固定の基になる型を持たない列挙定義内で、列挙子の型が初期化子によって決定されるように指定します。 または、初期化子のない列挙子の場合は、(オーバーフローを考慮して) 直前の列挙子の型によって決定されます。 以前は、このような列挙子には、基となる型のプレースホルダー (通常は int
) と共に、列挙型の推定型が常に指定されていました。
Visual Studio 2022 バージョン 17.4 より前のバージョンの Visual Studio に含まれる C++ コンパイラでは、固定の基本データ型がない、スコープを持たない列挙型の基となる型が正しく判断されませんでした。 コンパイラも、列挙子の型を正しくモデル化しませんでした。 列挙型の右中かっこの前に固定の基となる型がない場合、列挙型で不適切な型が想定される可能性がありました。 /Zc:enumTypes
では、コンパイラは標準動作を正しく実装します。
例: 固定型のないスコープ外の enum
の基になる型
enum Unsigned
{
A = 0xFFFFFFFF // Value 'A' does not fit in 'int'.
};
// Previously, this static_assert failed. It passes with /Zc:enumTypes.
static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned int>);
template <typename T>
void f(T x)
{
}
int main()
{
// Previously called f<int>, now calls f<unsigned int>.
f(+A);
}
// Previously, this enum would have an underlying type of `int`,
// but Standard C++ requires this to have a 64-bit underlying type.
// The /Zc:enumTypes option changes the size of this enum from 4 to 8,
// which could impact binary compatibility with code compiled with an
// earlier compiler version, or without the switch.
enum Changed
{
X = -1,
Y = 0xFFFFFFFF
};
例: 固定の基になる型を持たない enum
定義内の列挙子
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
でした。B
は sizeof(Enum)
(つまり 4) を使って初期化されていました。
このコンパイラ オプションを Visual Studio で使用するには
プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳細については、Visual Studio での C++ コンパイラとビルド プロパティの設定に関する記事を参照してください。
[構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。
[追加のオプション] で、
/Zc:enumTypes
または/Zc:enumTypes-
を追加します。 [OK] または [適用] を選択して、変更内容を保存します。