Share via


編譯器警告 (層級 4) C4471

' enumeration ': Unscoped 列舉的正向宣告必須具有基礎類型(假設為 int)

找不到未指定範圍列舉的正向宣告,但沒有基礎類型的規範。 根據預設,Visual C++ 假設 int 是列舉的基礎類型。 如果列舉定義中使用了不同的類型,例如,如果指定了不同的明確型別,或初始化運算式隱含設定不同的類型,這可能會導致問題。 您可能也有可攜性問題;其他編譯器不假設 int 是列舉的基礎類型。

此警告預設為關閉;您可以使用 /Wall 或 /w N 4471 在命令列上啟用它,或在原始程式檔中使用 #pragma 警告

範例

在某些情況下,這個警告是假的。 如果列舉的正向宣告出現在定義之後,可能會引發這個警告。 例如,此程式碼是有效的,即使它可能會導致 C4471:

// C4471a.cpp
// Compile with: cl /c /w14471 C4471a.cpp
enum Example { item = 0x80000000UL };
enum Example;    // Spurious C4471
// ...

一般而言,使用未範圍列舉的完整定義,而不是正向宣告是安全的。 您可以將定義放在標頭檔中,並將其包含在參考它的來源檔案中。 這適用于針對 C++98 和更新版本撰寫的程式碼。 我們建議此解決方案以方便移植和維護。

// C4471b.cpp
// Compile with: cl /c /w14471 C4471b.cpp
enum Example;    // C4471
// To fix, replace the line above with the enumeration definition:
// enum Example { item = 0x80000000UL };
// ...

在 C++11 中,您可以將明確型別新增至未範圍列舉和其轉送宣告。 只有當複雜的標頭包含邏輯無法使用定義,而不是正向宣告時,我們才建議此解決方案。 此解決方案可能會導致維護問題:如果您變更列舉定義所使用的基礎類型,您也必須變更所有正向宣告以符合,或程式碼中可能有無訊息錯誤。 您可以將轉送宣告放在標頭檔中,以將此問題降到最低。

原始程式檔 C4471c.cpp

// C4471c.cpp
// Client code for enumeration defined in C4471d.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example;    // C4471, int assumed
// To fix, replace the lines above with the forward declarations:
// enum Example : unsigned;
// ...

原始程式檔 C4471d.cpp

// C4471d.cpp
// Definition for enumeration used in C4471c.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example : unsigned { item = 0x80000000 }; // explicit type
// ...

如果您指定列舉的明確類型,建議您也啟用預設為開啟的警告 C4369 。 這會識別列舉專案需要與明確指定型別不同的案例。

您可以將程式碼變更為使用範圍列舉,這是 C++11 中的新功能。 使用列舉型別的定義和任何用戶端程式代碼都必須變更為使用範圍列舉。 如果您有命名空間污染的問題,建議您使用範圍列舉,因為定義的列舉專案名稱僅限於列舉的範圍。 範圍列舉的另一個功能是其成員無法隱含地轉換成另一個整數或列舉類型,這可以是細微 Bug 的來源。

原始程式檔 C4471e.cpp

// C4471e.cpp
// Client code for scoped enumeration defined in C4471f.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum Example;    // C4471
// To fix, replace the line above with the forward declaration:
// enum class Example;
// ...

原始程式檔 C4471f.cpp

// C4471f.cpp
// Definition for scoped enumeration used in C4471e.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum class Example { item = 0 };
// ...