Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Variable de type enumeration

63 réponses
Avatar
candide
Bonjour,

La norme C90 dit

--------------------------- 8< ------------------------------------
Each enumerated type shall be compatible with an integer type; the
choice of type is implementation-defined.
--------------------------- >8 ------------------------------------

Ce qui n'est pas très clair c'est que par ailleurs :

--------------------------- 8< ------------------------------------
An identifier declared as an enumeration constant has type int.
--------------------------- >8 ------------------------------------

Je me pose donc la question de savoir si on peut utiliser sans risque
une variable de type énumération exactement comme s'il s'agissait d'une
variable de type int ? Je dis "sans risque" parce que formellement, je
crois que rien ne m'en empêche :

--------------------------- 8< ------------------------------------
A char, a short int, or an int bit-field, or their signed or
unsigned varieties, or an object that has enumeration type, may be
used in an expression wherever an int or unsigned int may be used.
--------------------------- >8 ------------------------------------

Si, par exemple

enum toto {A=34, B=51} t;

peut-on écrire

t=28;

(cela pourrait poser problème si l'on considère que les valeurs prises
par une variable de type enum toto sont parmi 34 et 51, cf. ma première
citation de la norme) ? Bon, en fait j'imagine que ça ne pose pas de
problème particulier mais je trouve que la norme n'est pas formelle sur
ce point. Par contre, pourrait-il y avoir des problèmes si on écrivait

t=-5;

?

Quelles précautions particulières prendre avec des variables de type
énumération ? Harbison & Steele recommandent une certaine prudence :


--------------------------- 8< ------------------------------------
We suggest that programmers treat enumerated types as different from
integers and not mix them in integer expressions without using casts.
--------------------------- >8 ------------------------------------

mais ils ne donnent aucun exemple illustrant les précautions à prendre.
Concrètement faut faire quoi ? Ainsi dans mon premier exemple ci-dessus,
dois-je écrire

t=(enum toto) 28;

?

Merci.

10 réponses

1 2 3 4 5
Avatar
candide
candide a écrit :


enum toto {A4, BQ} t;

peut-on écrire

t(;

(cela pourrait poser problème si l'on considère que les valeurs prises
par une variable de type enum toto sont parmi 34 et 51,





K&R2 répond à ma question :


---------------------- 8< --------------------------------------------
Although variables of enum types may be declared, compilers need not
check that what you store in such a variable is a valid value for the
enumeration.
---------------------- >8 --------------------------------------------

(bien que la formulation soit encore assez imprécise).
Avatar
Thierry B.
--{ candide a plopé ceci: }--

enum toto {A4, BQ} t;
peut-on écrire
t(;




Ayant la vilaine habitude d'écrire du code crade, puis-je me
permettre de dire que "ça", je ne le ferais jamais ?

Même la programmation de goret doit avoir ses limites, non ?


--
Bonaventure Pochard :
Je cherche un bon jeu de poker pour PC ( de préférence gratuit). Que me
conseillez-vous ?


Bon sang Pochard, qu'est ce que vous avez encore inventé comme AAD ?


Avatar
Wykaaa
candide a écrit :
Bonjour,

La norme C90 dit

--------------------------- 8< ------------------------------------
Each enumerated type shall be compatible with an integer type; the
choice of type is implementation-defined.
--------------------------- >8 ------------------------------------

Ce qui n'est pas très clair c'est que par ailleurs :

--------------------------- 8< ------------------------------------
An identifier declared as an enumeration constant has type int.
--------------------------- >8 ------------------------------------

Je me pose donc la question de savoir si on peut utiliser sans risque
une variable de type énumération exactement comme s'il s'agissait d'une
variable de type int ? Je dis "sans risque" parce que formellement, je
crois que rien ne m'en empêche :

--------------------------- 8< ------------------------------------
A char, a short int, or an int bit-field, or their signed or
unsigned varieties, or an object that has enumeration type, may be
used in an expression wherever an int or unsigned int may be used.
--------------------------- >8 ------------------------------------

Si, par exemple

enum toto {A4, BQ} t;

peut-on écrire

t(;

(cela pourrait poser problème si l'on considère que les valeurs prises
par une variable de type enum toto sont parmi 34 et 51, cf. ma première
citation de la norme) ? Bon, en fait j'imagine que ça ne pose pas de
problème particulier mais je trouve que la norme n'est pas formelle sur
ce point. Par contre, pourrait-il y avoir des problèmes si on écrivait

t=-5;

?

Quelles précautions particulières prendre avec des variables de type
énumération ? Harbison & Steele recommandent une certaine prudence :


--------------------------- 8< ------------------------------------
We suggest that programmers treat enumerated types as different from
integers and not mix them in integer expressions without using casts.
--------------------------- >8 ------------------------------------

mais ils ne donnent aucun exemple illustrant les précautions à prendre.
Concrètement faut faire quoi ? Ainsi dans mon premier exemple ci-dessus,
dois-je écrire

t=(enum toto) 28;

?

Merci.


La dernière recommandation d'Harbison & Steele est tout à fait
pertinente et doit être suivie. De toute façon, le livre d'Harbison &
Steele est, à mon avis, le meilleur livre sur C.

J'ai une question, cependant, à propos de tes interrogations :
Pourquoi vouloir à tout prix "utiliser une variable de type enum
exactement comme une variable de type int" ?
Ou tes questions ne sont-elles là que pour illustrer que la norme n'est
pas très clair sur la frontière enum/int ?

Ou, autrement dit, pourquoi vouloir utiliser des enum comme des int ?
Dans ce cas, il vaut mieux ne pas utiliser d'enum.

J'ai fait un compilo C et dans lequel les enum étaient effectivement
implémentés comme des int mais ce n'est pas une raison pour les traiter
comme tels.

Par ailleurs, le langage C est très laxiste sur les conversions implicites.
J'ai une règle de programmation intangible (que je respecte toujours) :
j'explicite toujours les conversions même dans les langages qui
admettent des conversions implicites. Cette habitude me vient du langage
ADA qui n'admet AUCUNE conversion implicite (même de entier vers flottant).
De cette façon, j'ai beaucoup moins de "surprises" que mes collègues.
Avatar
candide
Wykaaa a écrit :

pertinente et doit être suivie. De toute façon, le livre d'Harbison &
Steele est, à mon avis, le meilleur livre sur C.



Voilà donc qui n'est pas très flatteur pour la littérature sur le C.


Pourquoi vouloir à tout prix "utiliser une variable de type enum
exactement comme une variable de type int" ?
Ou tes questions ne sont-elles là que pour illustrer que la norme n'est
pas très clair sur la frontière enum/int ?



Je voulais éclaicir les conséquences de ce que dit la norme et aussi
connaître la façon reconnue d'utiliser des variables de type enum.
Avatar
espie
In article <4870c68a$0$15462$,
candide wrote:
Wykaaa a écrit :

pertinente et doit être suivie. De toute façon, le livre d'Harbison &
Steele est, à mon avis, le meilleur livre sur C.



Voilà donc qui n'est pas très flatteur pour la littérature sur le C.



Je ne vois pas de lien logique. Dire qu'un bouquin est `le meilleur sur
le langage' ne veut pas dire que les autres soient mauvais. Ou alors,
tu n'aimes pas Harbison & Steele ?

Manque de bol, sur un axe tres precis, c'est effectivement un des meilleurs
bouquins existants: c'est un tres bon ouvrage de reference vis-a-vis du
langage. Forcement moins exact que la norme, par construction, mais egalement
sensiblement plus digeste.

Je ne l'ai jamais pris en defaut jusqu'ici.

Par contre, ca n'est clairement pas un bouquin d'apprentissage du C.
Mais, sur ce plan, je ne sais pas s'il existe grand chose de correct en
dehors du K&R (qui est fort bien, mais quelque peu limite parfois)...
les autres bouquins auxquels j'ai jete un oeil sont le plus souvent
largement pires (en particulier, remplis d'erreurs et d'inexactitudes).
Avatar
candide
Marc Espie a écrit :
Ou alors,
tu n'aimes pas Harbison & Steele ?



Très exactement. Et j'ai lu intégralement, crayon rageur à la main de la
page 1 à la page 324 donc tout ce qui concerne le langage et les
généralités concernant le_s_ bibliothèque_s_ (sic). Je me suis dispensé
de lire la descriptions une à une des fonctions standard mais je
consulte souvent la partie que je n'ai pas lu concernant des points
importants et délicats ou des questions ponctuelles. Je le consulte très
très souvent par ailleurs et ce sont toujours les mêmes défauts qui
reviennent d'absence de clarté, de mauvaise navigabilité (facheux pour
un ouvrage de référence). Je n'en finirais pas d'énumérer les défauts de
cet ouvrage un des pires que je connaisse, du mauvais travail, et comme
on en est à la cinquième édition, c'est que le travail était mal né. Je
ne remets pas pour autant en cause la compétence des auteurs, je crois
qu'elles est connue et reconnue.


Manque de bol, sur un axe tres precis, c'est effectivement un des meilleurs
bouquins existants: c'est un tres bon ouvrage de reference vis-a-vis du
langage. Forcement moins exact que la norme, par construction, mais egalement
sensiblement plus digeste.



Même pas sûr.


Je ne l'ai jamais pris en defaut jusqu'ici.



Va voir l'errata tu seras impressionné de sa longueur. Des pans entiers
sont incorrects aux dires même des auteurs.



Par contre, ca n'est clairement pas un bouquin d'apprentissage du C.



Non mais le niveau est étonnement hétérogène : il glose sur du trivial
et néglige le délicat.



Mais, sur ce plan, je ne sais pas s'il existe grand chose de correct en
dehors du K&R (qui est fort bien, mais quelque peu limite parfois)...



Fort bien ? bof, c'est un très mauvais ouvrage d'apprentissage, écrit
avec peu de rigueur pédagogique ou plutôt avec une rigueur pédagogique
très inégale, lumineux parfois, obscur et surchargé souvent. Je précise
que j'ai lu l'ouvrage crayon à la main de A à Z et c'est l'ouvrage que
je consulte en priorité pour tenter d'avoir une vue d'ensemble sur une
question donné sans compter qu'il contient du code hautement
idiomatique. Disons que le bouquin est correct quand on connait déjà
assez bien le langage ce qui est fâcheux pour un ouvrage qui est censé
vous l'apprendre.


les autres bouquins auxquels j'ai jete un oeil sont le plus souvent
largement pires (en particulier, remplis d'erreurs et d'inexactitudes).



Hélas, il n'existe aucun bouquin ni même document décent sur le C (j'en
ai consulté ou lu des dizaines) mais il existe une multiplicité de
références plus ou moins correctes sur tel ou tel point plus ou moins
important. C'est pas compliqué tu prends une à une les questions plus ou
moins basiques sur le C qu'on lisait sur fclc il y a quelques années ou
encore maintenant sur clc voire sur csc et tu dois te rendre compte que
la réponse n'est dans aucun document figé. Pourtant, ces questions
répondent à un savoir figé (le C est une langue morte bien que toujours
parlé et étudié) et est connu de nombreuses personnes. Bien sûr, ce que
je te dis là vaut de beaucoup d'autres choses, en particulier tout ce
qui touche à l'utilisation d'outils informatiques où le savoir ne passe
pas par la documentation à moins d'être du sérail. Faut pas s'étonner
des succès de sites du genre le siteduzéro.
Avatar
espie
In article <4870d5e3$0$9620$,
candide wrote:
Hélas, il n'existe aucun bouquin ni même document décent sur le C (j'en
ai consulté ou lu des dizaines) mais il existe une multiplicité de
références plus ou moins correctes sur tel ou tel point plus ou moins
important. C'est pas compliqué tu prends une à une les questions plus ou
moins basiques sur le C qu'on lisait sur fclc il y a quelques années ou
encore maintenant sur clc voire sur csc et tu dois te rendre compte que
la réponse n'est dans aucun document figé. Pourtant, ces questions
répondent à un savoir figé (le C est une langue morte bien que toujours
parlé et étudié) et est connu de nombreuses personnes. Bien sûr, ce que
je te dis là vaut de beaucoup d'autres choses, en particulier tout ce
qui touche à l'utilisation d'outils informatiques où le savoir ne passe
pas par la documentation à moins d'être du sérail. Faut pas s'étonner
des succès de sites du genre le siteduzéro.



Je pense qu'une partie de tes recherches sont totalement inutiles.
Les gens qui programment en C pour de vrai, dont je fais partie, ont
une tendance tres nette a NE PAS utiliser les bouts du langage les moins
clairs et les plus vicieux. Si ce sont des morceaux pour lesquels il est
difficile de trouver des reponses, il y a de tres fortes chances qu'une
part non negligeable des implementations soient fausses...

Typiquement, tes questions recentes sur les enum. Les points un peu
bizarres de typage des enums font qu'une enum est tres rarement une bonne
idee, et qu'en tout cas il vaut mieux ne pas dependre des points obscurs
de la norme.

On peut faire enormement de choses utiles ET fonctionnant en restant
dans un petit sous-ensemble du langage, fort heureusement!

Les bouts obscurs ne me servent que:
- lorsque je dois faire du boulot d'archeologiste sur du code existant
pour lequel je suis a peu pres sur qu'il y a des erreurs a corriger;
- lorsque je suis en train de corriger un bout de l'implementation qui
m'interesse, a savoir le C tel que vu par mon systeme OpenBSD. Dans ce
cas (et dans ce cas seulement), je joue parfois au `language lawyer'.

le reste du temps, plus c'est simple et non ambigu, et mieux je me porte...
Avatar
candide
Marc Espie a écrit :


Les gens qui programment en C pour de vrai, dont je fais partie, ont
une tendance tres nette a NE PAS utiliser les bouts du langage les moins
clairs et les plus vicieux.



Je m'imagine à leur place et je pense que je ferais pareil. Mais bon, je
suis moins intéressé par la programmation en C que par son apprentissage
ou sa glose.

Mais à vrai dire, l'avis qui m'intéresse le plus est celui des
praticiens comme toi (et qui font qu'un langage mort peut être encore
vivant).

Le problème est qu'il faudrait délimiter objectivement ces questions se
référant à ces parties peu claires et vicieuses. Empoignades
interminables garanties.

Pour toi, j'ai retenu qu'il y avait déjà les variables globales (même si
le problème est un peu différent), les macro-fonctions et les enum.

Si ce sont des morceaux pour lesquels il est
difficile de trouver des reponses, il y a de tres fortes chances



T'es un pragmatique toi !

qu'une
part non negligeable des implementations soient fausses...



Implémentation de quoi ? du langage C ? parce qu'on mettre aussi en
cause les mauvaises pratiques des programmeurs et les incohérences
éventuelles de la norme.


Typiquement, tes questions recentes sur les enum. Les points un peu
bizarres de typage des enums font qu'une enum est tres rarement une bonne
idee, et qu'en tout cas il vaut mieux ne pas dependre des points obscurs
de la norme.




Je pense que ton avis sur les enum est loin de faire l'unanimité. Et si
tu regardes du code sérieux, tu sais bien que les énumérations sont très
utilisées.

En deux mots, pourrais-tu donner un exemple de code montrant un problème
soulevé par un type énuméré et dire par quoi tu remplaces tes enum (des
macro-constantes ? des variables const ?)

Tiens, pour alimenter la discussion, voici ce que dit K&R des
énumérations (numérotation et passages à la lignes sont de moi) :

-----------------------------------------------------------------------
Enumerations provide a convenient way to associate constant values with
names, an alternative to #define with the advantage that
(1) the values can be generated for you.

(2) Although variables of enum types may be declared, compilers need not
check that what you store in such a variable is a valid value for the
enumeration.


(3) Nevertheless, enumeration variables offer the chance of checking and
so are often better than #defines. In addition, a debugger may be able
to print values of enumeration variables in their symbolic form.
-----------------------------------------------------------------------

Mes questions :

(1) je comprends ce qu'il veut dire par ça. En clair, c'est quoi
l'avantage ? qu'on dispose de vraies variables ?

(2) phrase très ambiguë. Je vais quand même avoir un problème si je mets
un flottant dans une variable de type enum toto, ça le compilateur il va
le voir.

(3) le checking, un réel avantage ? meilleure sécurité ?

Par ailleurs, je précise que Kernighan et Pike recommandent dans "The
Pratice of Programming" (page 20) :

---------------- 8< ----------------------
Define numbers as constants, not macros.
[...]In C and C++, integer constants can be defined with an enum
statement as we saw in the previous example. [...]C has also const
values but they cannot be used as array bounds, so the enum statement
remains the method of choice in C.
------------------ >8 ---------------------
Avatar
candide
candide a écrit :

Par ailleurs, je précise que Kernighan et Pike recommandent dans "The
Pratice of Programming" (page 20) :

---------------- 8< ----------------------
[...]In C and C++, integer constants can be defined with an enum
statement



[...] so the enum statement
------------------ >8 ---------------------




Tiens "enum statement" ? ça existe ça ? Ce serait pas plutôt "enum
declaration" ?
Avatar
Wykaaa
candide a écrit :
Wykaaa a écrit :

pertinente et doit être suivie. De toute façon, le livre d'Harbison &
Steele est, à mon avis, le meilleur livre sur C.



Voilà donc qui n'est pas très flatteur pour la littérature sur le C.



Il est vrai que la littérature sur le langage C n'est pas terrible, à
commencer par le livre des auteurs du langage lui-même dans lequel de
nombreux exemples de code sont justement plutôt des exemples de ce qu'il
ne faudrait pas écrire en C...


Pourquoi vouloir à tout prix "utiliser une variable de type enum
exactement comme une variable de type int" ?
Ou tes questions ne sont-elles là que pour illustrer que la norme
n'est pas très clair sur la frontière enum/int ?



Je voulais éclaicir les conséquences de ce que dit la norme et aussi
connaître la façon reconnue d'utiliser des variables de type enum.



Il faut utiliser les enum en C pour ce qu'ils sont et les services
qu'ils peuvent rendre :
- augmenter la lisibilité des programmes. Il est toujours préférable de,
par exemple, nommer les jours que de se servir de 1, 2, 3, ..., 7
- Les enum doivent être utilisés conjointement avec switch.

D'une façon générale, il faut utiliser les enums en C comme ils sont
utilisés dans les autres langages, en particulier ADA.
Et surtout, il ne faut JAMAIS mélanger les enum et les int !
1 2 3 4 5