/Zc:enumTypes
(啟用列舉類型扣減)
編譯程式 /Zc:enumTypes
選項可讓C++符合 enum
基礎類型和列舉值類型推算。
語法
/Zc:enumTypes
[-
]
備註
編譯 /Zc:enumTypes
程式選項會實作標準C++符合列舉基底型別和列舉值型別的推算行為。
此選項 /Zc:enumTypes
是 Visual Studio 2022 17.4 版的新功能。 這個選項預設為關閉,且 未由 /permissive-
啟用。 若要明確停用 選項,請使用 /Zc:enumTypes-
。
啟用時,/Zc:enumTypes
選項是潛在的來源和二進位中斷性變更。 啟用符合 /Zc:enumTypes
選項時,某些列舉型別會變更大小。 某些 Windows SDK 標頭包含這類列舉定義。
C++ Standard 要求列舉的基礎類型夠大,足以保存其中宣告的所有列舉值。 足夠大的列舉程式可以將 enum
的基礎型別設定為 unsigned int
、long long
或 unsigned long long
。 先前,不論列舉值為何,這類列舉型別在Microsoft編譯程式中一律有 的基礎型 int
別。
C++ Standard 也指定,在沒有固定基礎類型的列舉定義中,列舉值的類型是由其初始化表達式所決定。 或者,對於沒有初始設定式的列舉程式,依照前一個列舉程式的型別 (考慮溢位)。 先前這類列舉程式一律會獲得列舉的推算型別,並具有基礎型別的預留位置 (通常是 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-
。 選擇 [確定] 或 [套用] 以儲存變更。