type enum vérifier en C/gcc
Voir l'exemple simple ci-dessous. Quand une fonction retournant un enum
est affecté à une variable d'un autre enum
je n'obtiens aucun avertissement, même avec gcc -Wall -pedantic
. Pourquoi n'est-il pas possible pour un compilateur C pour faire de ce type de vérification sur enum
s? Ou est-il gcc
spécifique? Je n'ai pas accès à tout autre compilateur droit maintenant pour l'essayer..
enum fruit {
APPLE,
ORANGE
};
enum color {
RED,
GREEN
};
static inline enum color get_color() {
return RED;
}
int main() {
enum fruit ftype;
ftype = get_color();
}
Vous devez vous connecter pour publier un commentaire.
Cette déclaration:
déclare trois choses: un type appelé
enum fruit
, et deux agents recenseurs ont appeléapple
etorange
.enum fruit
est en fait un type distinct. Il est compatible avec certains de la mise en œuvre définies de type entier; par exemple,enum fruit
peut être compatible avecint
, avecchar
, ou même avecunsigned long long
si la mise en œuvre choisit de le faire, aussi longtemps que le type choisi peut représenter toutes les valeurs.Les agents recenseurs, d'autre part, sont des constantes de type
int
. En fait, il y a un truc commun de l'aide d'un nuenum
déclaration de déclarerint
constantes sans l'aide du préprocesseur:Oui, cela signifie que la constante de
apple
, même si elle a été déclarée comme faisant partie de la définition deenum fruit
, n'est-ce pas en fait de typeenum fruit
. Les raisons en sont historiques. Et oui, il aurait probablement fait plus de sens pour les agents recenseurs pour être des constantes du type.Dans la pratique, cette incohérence rarement des questions beaucoup. Dans la plupart des contextes, discret types (c'est a dire entier et l'énumération des types) sont largement interchangeables, et les conversions implicites généralement de faire la bonne chose.
Mais le résultat est que, comme vous l'avez vu, le compilateur n'est pas susceptible de vous avertir si vous utilisez une constante associée à un type énuméré quand tu veux en utiliser un autre.
Une manière type de vérification est d'envelopper vos données dans une structure (struct):
struct fruit
etstruct color
sont distinctes et les types incompatibles avec aucune implicite (ou explicite) de conversion d'entre eux. L'inconvénient est que vous devez vous référer à la.f
ou.c
membre explicitement. (La plupart des programmeurs C de ne compter que sur leur capacité à faire les choses, en premier lieu, -- avec des résultats mitigés.)(
typedef
ne vous donne pas la vérification de type fort; malgré le nom, il crée un alias pour un type existant, pas d'un nouveau type.)(Les règles en C++ sont un peu différentes.)
Probablement la plupart d'entre nous de comprendre les causes sous-jacentes ("la spec dit qu'il faut travailler"), mais nous sommes également d'accord que c'est une cause de beaucoup d'erreurs de programmation en "C" la terre et que la structure d'habillage solution de contournement est brut. Ignorant add-on pions tels que peluches, voici ce que nous avons:
gcc
décidé de ne pas les prévenir (comme le faitclang
) maisicc
(Intel compilateur) garde dans cette situation. Si vous voulez quelques autres type de vérification pourenum
types, vous pouvez passer votre code à code statique checker commeLint
qui est en mesure d'avertir dans de tels cas.gcc
a décidé qu'il n'était pas utile d'avertir pour les conversions implicites entreenum
types, mais note également que le C ne nécessite pas la mise en œuvre d'émettre un diagnostic en cas de cession entre deuxenum
types. C'est le même que pour l'affectation entre l'arithmétique type: diagnostic n'est pas nécessaire de C. Par exemple,gcc
aussi de ne pas avertir si vous affectez unlong long
à unchar
ou unshort
à unlong
.C'est parce que
enum
s dans C sont tout simplement un groupe de unique des constantes entières, que vous éviter d'avoir à#define
tout un tas de constantes. C'est pas comme en C++ où leenum
s que vous créez sont d'un type spécifique. C'est juste la façon dont C est.Il est également intéressant de noter que la taille réelle utilisée pour représenter
enum
valeurs dépend du compilateur.Un enum en C est essentiellement traité comme un entier. C'est juste une plus belle façon d'utiliser les constantes.
Vous pouvez également spécifier les valeurs:
gcc gars ont toujours une raison de ne pas faire quelque chose.
Utiliser clang avec des options
-Wenum-conversion -Wassign-enum
.