Udostępnij za pośrednictwem


Ostrzeżenie kompilatora (poziom 4) C4471

"wyliczenie": deklaracja przesyłania dalej wyliczenia niezakresowego musi mieć typ bazowy (zakładane int)

Znaleziono deklarację przesyłania dalej niezakresowego wyliczenia bez specyfikatora dla typu bazowego. Domyślnie język Visual C++ zakłada int , że jest podstawowym typem wyliczenia. Może to spowodować problemy, jeśli w definicji wyliczenia jest używany inny typ, na przykład jeśli określono inny jawny typ lub czy inny typ jest niejawnie ustawiany przez inicjator. Mogą również wystąpić problemy z przenośnością; inne kompilatory nie zakładają int , że jest podstawowym typem wyliczenia.

To ostrzeżenie jest domyślnie wyłączone; Możesz użyć /Wall lub /wN4471, aby włączyć go w wierszu polecenia, lub użyć #pragma ostrzeżenie w pliku źródłowym.

Przykłady

W niektórych przypadkach to ostrzeżenie jest fałszywe. Jeśli po definicji pojawi się deklaracja przesyłania dalej dla wyliczenia, to ostrzeżenie może zostać wyzwolony. Na przykład ten kod jest prawidłowy, mimo że może to spowodować C4471:

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

Ogólnie rzecz biorąc, można bezpiecznie użyć pełnej definicji wyliczenia niezakresowego zamiast deklaracji do przodu. Definicję można umieścić w pliku nagłówka i uwzględnić w plikach źródłowych odwołujących się do niego. Działa to w kodzie napisanym dla języka C++98 i nowszych. Zalecamy to rozwiązanie pod kątem przenośności i łatwości konserwacji.

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

W języku C++11 można dodać jawny typ do wyliczenia niezakresowego i do jego deklaracji przesyłania dalej. Zalecamy to rozwiązanie tylko wtedy, gdy złożona logika dołączania nagłówka uniemożliwia użycie definicji zamiast deklaracji przesyłania dalej. To rozwiązanie może prowadzić do problemu z konserwacją: w przypadku zmiany typu bazowego używanego dla definicji wyliczenia należy również zmienić wszystkie deklaracje przesyłania dalej tak, aby były zgodne, lub w kodzie mogą występować błędy dyskretne. Możesz umieścić deklarację do przodu w pliku nagłówka, aby zminimalizować ten problem.

Plik C4471c.cppźródłowy:

// 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;
// ...

Plik C4471d.cppźródłowy:

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

Jeśli określisz jawny typ wyliczenia, zalecamy również włączenie ostrzeżenia C4369, które jest domyślnie włączone. Określa to przypadki, w których element wyliczenia wymaga innego typu niż jawnie określony typ.

Możesz zmienić kod, aby użyć wyliczenia o określonym zakresie— funkcji, która jest nowa w języku C++11. Aby użyć wyliczenia o określonym zakresie, należy zmienić zarówno definicję, jak i dowolny kod klienta, który używa typu wyliczenia w zakresie. Zalecamy użycie wyliczenia o określonym zakresie, jeśli masz problemy z zanieczyszczeniem przestrzeni nazw, ponieważ nazwy zdefiniowanych elementów wyliczenia są ograniczone do zakresu wyliczenia. Inną funkcją wyliczenia o określonym zakresie jest to, że jego składowe nie mogą być niejawnie konwertowane na inny typ całkowity lub wyliczenia, który może być źródłem drobnych usterek.

Plik C4471e.cppźródłowy:

// 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;
// ...

Plik C4471f.cppźródłowy:

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