Compilerwarnung (Ebene 4) C4471
“enumeration“: Für eine Vorwärtsdeklaration einer Enumeration ohne Bereichseinschränkung ist ein zugrunde liegender Typ erforderlich (int wird angenommen).
Eine Vorwärtsdeklaration einer nicht bereichsorientierten Aufzählung wurde ohne Bezeichner für den zugrunde liegenden Typ gefunden. Visual C++ geht standardmäßig davon aus, dass int
es sich bei visual C++ um den zugrunde liegenden Typ einer Enumeration handelt. Dies kann Zu Problemen führen, wenn in der Enumerationsdefinition ein anderer Typ verwendet wird, z. B. wenn ein anderer expliziter Typ angegeben wird oder ein anderer Typ implizit von einem Initialisierer festgelegt wird. Möglicherweise haben Sie auch Portabilitätsprobleme; Andere Compiler gehen nicht davon aus, dass int
es sich um den zugrunde liegenden Typ einer Enumeration handelt.
Diese Warnung ist standardmäßig deaktiviert; Sie können /Wall oder /wN4471 verwenden, um sie in der Befehlszeile zu aktivieren, oder #pragma Warnung in der Quelldatei verwenden.
Beispiele
In einigen Fällen ist diese Warnung scheinhaft. Wenn nach der Definition eine Weiterleitungsdeklaration für eine Enumeration angezeigt wird, kann diese Warnung ausgelöst werden. Dieser Code ist beispielsweise gültig, auch wenn er C4471 verursachen kann:
// C4471a.cpp
// Compile with: cl /c /w14471 C4471a.cpp
enum Example { item = 0x80000000UL };
enum Example; // Spurious C4471
// ...
Im Allgemeinen ist es sicher, die vollständige Definition für eine nicht bereichsorientierte Enumeration anstelle einer Weiterleitungsdeklaration zu verwenden. Sie können die Definition in eine Headerdatei einfügen und in Quelldateien einfügen, die darauf verweisen. Dies funktioniert im Code, der für C++98 und höher geschrieben wurde. Wir empfehlen diese Lösung für Portabilität und einfache Wartung.
// 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 };
// ...
In C++11 können Sie einer nicht bereichsorientierten Aufzählung und der weiterleitungsdeklaration einen expliziten Typ hinzufügen. Wir empfehlen diese Lösung nur, wenn komplexe Headereinschlusslogik die Verwendung der Definition anstelle einer Weiterleitungsdeklaration verhindert. Diese Lösung kann zu einem Wartungsproblem führen: Wenn Sie den zugrunde liegenden Typ ändern, der für die Enumerationsdefinition verwendet wird, müssen Sie auch alle Weiterleitungsdeklarationen so ändern, dass sie übereinstimmen, oder Sie haben möglicherweise automatische Fehler im Code. Sie können die Vorwärtsdeklaration in eine Headerdatei einfügen, um dieses Problem zu minimieren.
Quelldatei 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;
// ...
Quelldatei 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
// ...
Wenn Sie einen expliziten Typ für eine Aufzählung angeben, wird empfohlen, auch die Warnung C4369 zu aktivieren, die standardmäßig aktiviert ist. Dadurch werden Fälle identifiziert, in denen ein Enumerationselement einen anderen Typ als den explizit angegebenen Typ erfordert.
Sie können Ihren Code ändern, um eine bereichsbezogene Enumeration zu verwenden, ein Feature, das in C++11 neu ist. Sowohl die Definition als auch der Clientcode, der den Enumerationstyp verwendet, müssen geändert werden, um eine bereichsbezogene Enumeration zu verwenden. Es wird empfohlen, eine bereichsbezogene Enumeration zu verwenden, wenn Probleme mit der Namespaceverschmutzung auftreten, da die Namen der definierten Enumerationselemente auf den Bereich der Enumeration beschränkt sind. Ein weiteres Feature einer bereichsbezogenen Enumeration besteht darin, dass ihre Member nicht implizit in einen anderen integralen oder Enumerationstyp konvertiert werden können, was eine Quelle subtiler Fehler sein kann.
Quelldatei 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;
// ...
Quelldatei 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 };
// ...