10
votes

Typeafe Enums en C?

Si j'en ai plus d'un Enum , par exemple: xxx

Comment puis-je appliquer l'utilisation du bon Enum ? Par exemple, je ne veux pas que quelqu'un utilise bonjour quand ils devraient utiliser un pour un meilleur débogage et une meilleure lisibilité.


0 commentaires

6 Réponses :


-3
votes

Vous pouvez tapedef votre énumé, puis déclarer des variables et des arguments de fonction de ces types.


0 commentaires

11
votes

Clang produit l'avertissement suivant, ce qui est le meilleur que vous puissiez faire (bien que l'utilisateur puisse mettre à niveau l'avertissement à une erreur).

cc     foo.c   -o foo
foo.c:8:17: warning: implicit conversion from enumeration type 'enum Count' to different enumeration type 'enum Greetings' [-Wenum-conversion]
        takes_greeting(one);
        ~~~~~~~~~~~~~~ ^~~
foo.c:9:14: warning: implicit conversion from enumeration type 'enum Greetings' to different enumeration type 'enum Count' [-Wenum-conversion]
        takes_count(hello);
        ~~~~~~~~~~~ ^~~~~


1 commentaires

Malheureusement, GCC ne produit pas un avertissement similaire en mode C. Je ne sais pas si MSVC fait ou ne le fait pas. Il y a quelques commentaires ici sur la manière de tromper GCC dans la production d'avertissements, au coût de la lisibilité.



3
votes

C'est la réponse que vous ne voulez pas entendre. En C, vous ne pouvez pas vraiment. Maintenant, si votre code C était dans le sous-ensemble "Clean C" de C ++, vous pouvez compiler avec le compilateur C ++ pour obtenir toutes les erreurs d'utilisation des mauvaises valeurs énum / int, etc.


1 commentaires

Même en C ++, ce n'est pas simple: vous avez besoin de fonctionnalité C ++ 11 "Enum Class", puis de spécifier le nom de la classe partout - par exemple. foo = salutations :: Bonjour ;



4
votes

Malheureusement, Enum code> est un point faible du système de type de C. Variables d'un type code> Enum code> de ce type Enum code> Type, mais Constantes que vous déclarez avec le Enum code> de type int code>.

donc dans votre exemple p> xxx pré>

Bonjour code> et one code> sont deux noms pour la même valeur, à savoir 0 code>, et avec le même type int code>. P >

holla code> et eins code> ont à nouveau une valeur 0 code>, mais ont leurs types respectifs. P>

Si vous voulez Forcez une certaine sécurité de type «officielle» pour les constantes «réelles», c'est-à-dire des entités qui ont le type et la valeur que vous souhaitez utiliser des constructions plus impliquées: P>

#define GREETING(VAL) ((enum Greetings){ 0 } = (VAL))
#define HELLO GREETING(hello)


0 commentaires

14
votes

en C, vous pouvez le simuler avec le code de la chairers.

$ gcc --version
powerpc-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


1 commentaires

Ceci est soigné, mais fait travailler avec Enums dans des déclarations de commutation un peu laides.



2
votes

Si vous souhaitez également vous assurer que la plage valide, il existe une technique avec la petite surcharge d'une déréférence de pointeur pour obtenir la valeur entière - et beaucoup de typographie de la chaudière. Il pourrait toujours être utile car il vous tire parti du code de vérification de la plage d'écriture où il serait nécessaire autrement.

salutations.h: p> xxx pré>

salutations.c: P>

const char *Greetings_str(const Greetings *g)
        __attribute__((nonnull(1)));


1 commentaires

Si l'utilisateur passe dans un null , il est préférable de planter le plus rapidement possible et de les laisser sortir. Ou, comme vous le dites, utilisez un tour spécifique au compilateur. Une petite amélioration que je peux suggérer est de simplement déplacer la chaîne de souhaits dans les salutations struct, car vous les traitez de toute façon. Donc, si vous aviez par ex. statique const salutations Bonjour = {0, "bonjour"}; , et ainsi de suite, vous pouvez simplement retour g-> étiquette dans la mise en œuvre.