Partilhar via


Aviso do compilador (nível 4) C4471

'enumeração': uma declaração antecipada de uma enumeração sem escopo deve ter um tipo subjacente (int assumido)

Observações

Uma declaração avançada de uma enumeração sem escopo foi encontrada sem um especificador para o tipo subjacente. Por padrão, o Visual C++ assume que int é o tipo subjacente para uma enumeração. Isso pode causar problemas se um tipo diferente for usado na definição de enumeração, por exemplo, se um tipo explícito diferente for especificado ou se um tipo diferente for definido implicitamente por um inicializador. Você também pode ter problemas de portabilidade; outros compiladores não assumem int que é o tipo subjacente de uma enumeração.

Este aviso está desativado por padrão; você pode usar /Wall ou /wN4471 para habilitá-lo na linha de comando ou usar #pragma aviso no arquivo de origem.

Examples

Em alguns casos, este aviso é espúrio. Se uma declaração antecipada para uma enumeração aparecer após a definição, este aviso poderá ser acionado. Por exemplo, este código é válido, mesmo que possa causar C4471:

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

Em geral, é seguro utilizar a definição completa para uma enumeração não enquadrada em vez de uma declaração antecipada. Você pode colocar a definição em um arquivo de cabeçalho e incluí-la em arquivos de origem que se referem a ela. Isso funciona em código escrito para C++98 e posterior. Recomendamos esta solução para portabilidade e facilidade de manutenção.

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

Em C++11, você pode adicionar um tipo explícito a uma enumeração sem escopo e à sua declaração de encaminhamento. Recomendamos esta solução somente se a lógica de inclusão de cabeçalho complexa impedir o uso da definição em vez de uma declaração antecipada. Essa solução pode levar a um problema de manutenção: se se alterar o tipo subjacente usado para a definição de enumeração, também deverá alterar todas as declarações avançadas para corresponder ou poderá ter erros silenciosos no seu código. Você pode colocar a declaração forward num ficheiro de cabeçalho para minimizar esse problema.

Ficheiro de origem 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;
// ...

Ficheiro de origem 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
// ...

Se você especificar um tipo explícito para uma enumeração, recomendamos que você também habilite o aviso C4369, que está ativado por padrão. Isso identifica casos em que um item de enumeração requer um tipo diferente do tipo explicitamente especificado.

Você pode alterar seu código para usar um enum com escopo, um recurso novo no C++11. Tanto a definição quanto qualquer código de cliente que use o tipo de enumeração devem ser alterados para usar um enum com escopo. Recomendamos que você use um enum com escopo se tiver problemas com a poluição do namespace, pois os nomes dos itens de enumeração definidos são limitados ao escopo do enum. Outra característica de um enum com escopo é que seus membros não podem ser implicitamente convertidos em outro tipo integral ou de enumeração, o que pode ser uma fonte de bugs sutis.

Ficheiro de origem 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;
// ...

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