C'est indéniable que c'est un avantage et que c'est un (petit) pas en
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de programmeurs
C qui maîtrisent totalement le langage (et encore).
En clair, si l'objectif de l'application est d'être extrêmement fiable
(car risque de perte de vies humaines sinon), je ne l'écrirait jamais en
langage C !!!
C'est indéniable que c'est un avantage et que c'est un (petit) pas en
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de programmeurs
C qui maîtrisent totalement le langage (et encore).
En clair, si l'objectif de l'application est d'être extrêmement fiable
(car risque de perte de vies humaines sinon), je ne l'écrirait jamais en
langage C !!!
C'est indéniable que c'est un avantage et que c'est un (petit) pas en
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de programmeurs
C qui maîtrisent totalement le langage (et encore).
En clair, si l'objectif de l'application est d'être extrêmement fiable
(car risque de perte de vies humaines sinon), je ne l'écrirait jamais en
langage C !!!
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
Wykaaa a écrit :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...
Pas tant que ça je trouve, tu pensais à quoi ?
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.
C'est aussi comme ça que je vois les choses, il suffit de lire comment
sont gérées les touches du clavier d'un quelconque jeu écrit en C : des
enum et des switch. Et c'est très lisible.
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 !
Donc tu abondes dans le sens de HS. Est-ce que tu aurais un exemple
précis du problème que ça peut poser ?
Donc un truc comme ça est fautif selon toi :
enum booleen {FAUX, VRAI} v1, v2=1-v1;
?
Wykaaa a écrit :
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...
Pas tant que ça je trouve, tu pensais à quoi ?
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.
C'est aussi comme ça que je vois les choses, il suffit de lire comment
sont gérées les touches du clavier d'un quelconque jeu écrit en C : des
enum et des switch. Et c'est très lisible.
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 !
Donc tu abondes dans le sens de HS. Est-ce que tu aurais un exemple
précis du problème que ça peut poser ?
Donc un truc comme ça est fautif selon toi :
enum booleen {FAUX, VRAI} v1, v2=1-v1;
?
Wykaaa a écrit :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...
Pas tant que ça je trouve, tu pensais à quoi ?
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.
C'est aussi comme ça que je vois les choses, il suffit de lire comment
sont gérées les touches du clavier d'un quelconque jeu écrit en C : des
enum et des switch. Et c'est très lisible.
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 !
Donc tu abondes dans le sens de HS. Est-ce que tu aurais un exemple
précis du problème que ça peut poser ?
Donc un truc comme ça est fautif selon toi :
enum booleen {FAUX, VRAI} v1, v2=1-v1;
?
- Les enum doivent être utilisés conjointement avec switch.
- Les enum doivent être utilisés conjointement avec switch.
- Les enum doivent être utilisés conjointement avec switch.
Wykaaa a écrit :langage. Forcement moins exact que la norme, par construction, mais
egalement
sensiblement plus digeste.
Même pas sûr.
Oh que si !
Oh que non ! Un exemple précis : Harbison and Steele sont infoutus dans
leur bouquin de définir ce que recouvre précisément le terme de
"statement" et il est FONDAMENTAL d'avoir des définitions précises en la
matière (cf. d'ailleurs la confusion déjà citée entre statement et
declaration). Dans HS, AUCUNE définition (alors qu'il y a un chapitre
portant le nom de "Statements" (chapitre 8). Incroyable ! de
l'amateurisme ! Et un jour, j'ai ouvert la norme et j'ai vu que le corps
du document contient des définitions relativement précises (en
particulier de "statement"). Et au début du texte il y a une clause qui
s'appelle "Definitions and conventions". Et tout a été amélioré entre
les versions de C90 à C99. Quand j'ai commencé le C, j'ai été accablé
par le jargon et un ouvrage de référence se doit d'en donner des
définitions, c'est évident.
Autre exemple : dans le § 5.5 sur les enumérations justement, ils ne
donnent AUCUN exemple d'une contruction d'une déclaration anonyme
d'énumération, un truc du genre :
enum {VRAI, FAUX};
eux systématiquement, ils écrivent
enum nonyme {VRAI, FAUX};
La norme, elle, donne des exemples pensés, et, ELLE, donne un tel
exemple. Or si je n'ai aucun exemple de certaines constructions (en plus
ici relativement usuelles), je ne vois pas comment je vais penser à les
utiliser à moins que je ne décide de déchiffrer la grammaire BNS du
langage C (ce qui est la présentation faite par HS et qu'ils
n'expliquent jamais, comme si tous les programmeurs de C connaissaient
la forme BNS d'une grammaire).
Et je pourrais multiplier les exemples où la norme est plus claire et
plus satisfaisante que HS.C'est une preuve d'honnêteté de la part des auteurs. D'autres, moins
scrupuleux, laissent leurs erreurs traîner de version en version...
En effet mais je m'étonne qu'à la 5ème édition, il en reste autant.
Le K&R est anti-pédagogique !
Il m'est arrivé plusieurs fois de préconiser aux participants d'un
cours sur le langage C de mettre ce livre à la poubelle. C'est un des
plus mauvais sur le langage (pour l'apprentissage, je préfère le
Harbison et Steele, c'est peu dire...)
Je n'aime pas trop le K&R car il m'a fait beaucoup souffrir. Mais plus
je connais le C plus je trouve que le livre a des qualités de synthèse.
Et du beau code bien concis.
J'aimais bien le bouquin de Philippe Drix : langage C, norme ANSI,
sous-titré, vers une approche objet.
J'ai beaucoup aimé ce livre même s'il n'est pas si facile à lire. Et il
m'a aidé à fixer pas mal de choses.
Wykaaa a écrit :
langage. Forcement moins exact que la norme, par construction, mais
egalement
sensiblement plus digeste.
Même pas sûr.
Oh que si !
Oh que non ! Un exemple précis : Harbison and Steele sont infoutus dans
leur bouquin de définir ce que recouvre précisément le terme de
"statement" et il est FONDAMENTAL d'avoir des définitions précises en la
matière (cf. d'ailleurs la confusion déjà citée entre statement et
declaration). Dans HS, AUCUNE définition (alors qu'il y a un chapitre
portant le nom de "Statements" (chapitre 8). Incroyable ! de
l'amateurisme ! Et un jour, j'ai ouvert la norme et j'ai vu que le corps
du document contient des définitions relativement précises (en
particulier de "statement"). Et au début du texte il y a une clause qui
s'appelle "Definitions and conventions". Et tout a été amélioré entre
les versions de C90 à C99. Quand j'ai commencé le C, j'ai été accablé
par le jargon et un ouvrage de référence se doit d'en donner des
définitions, c'est évident.
Autre exemple : dans le § 5.5 sur les enumérations justement, ils ne
donnent AUCUN exemple d'une contruction d'une déclaration anonyme
d'énumération, un truc du genre :
enum {VRAI, FAUX};
eux systématiquement, ils écrivent
enum nonyme {VRAI, FAUX};
La norme, elle, donne des exemples pensés, et, ELLE, donne un tel
exemple. Or si je n'ai aucun exemple de certaines constructions (en plus
ici relativement usuelles), je ne vois pas comment je vais penser à les
utiliser à moins que je ne décide de déchiffrer la grammaire BNS du
langage C (ce qui est la présentation faite par HS et qu'ils
n'expliquent jamais, comme si tous les programmeurs de C connaissaient
la forme BNS d'une grammaire).
Et je pourrais multiplier les exemples où la norme est plus claire et
plus satisfaisante que HS.
C'est une preuve d'honnêteté de la part des auteurs. D'autres, moins
scrupuleux, laissent leurs erreurs traîner de version en version...
En effet mais je m'étonne qu'à la 5ème édition, il en reste autant.
Le K&R est anti-pédagogique !
Il m'est arrivé plusieurs fois de préconiser aux participants d'un
cours sur le langage C de mettre ce livre à la poubelle. C'est un des
plus mauvais sur le langage (pour l'apprentissage, je préfère le
Harbison et Steele, c'est peu dire...)
Je n'aime pas trop le K&R car il m'a fait beaucoup souffrir. Mais plus
je connais le C plus je trouve que le livre a des qualités de synthèse.
Et du beau code bien concis.
J'aimais bien le bouquin de Philippe Drix : langage C, norme ANSI,
sous-titré, vers une approche objet.
J'ai beaucoup aimé ce livre même s'il n'est pas si facile à lire. Et il
m'a aidé à fixer pas mal de choses.
Wykaaa a écrit :langage. Forcement moins exact que la norme, par construction, mais
egalement
sensiblement plus digeste.
Même pas sûr.
Oh que si !
Oh que non ! Un exemple précis : Harbison and Steele sont infoutus dans
leur bouquin de définir ce que recouvre précisément le terme de
"statement" et il est FONDAMENTAL d'avoir des définitions précises en la
matière (cf. d'ailleurs la confusion déjà citée entre statement et
declaration). Dans HS, AUCUNE définition (alors qu'il y a un chapitre
portant le nom de "Statements" (chapitre 8). Incroyable ! de
l'amateurisme ! Et un jour, j'ai ouvert la norme et j'ai vu que le corps
du document contient des définitions relativement précises (en
particulier de "statement"). Et au début du texte il y a une clause qui
s'appelle "Definitions and conventions". Et tout a été amélioré entre
les versions de C90 à C99. Quand j'ai commencé le C, j'ai été accablé
par le jargon et un ouvrage de référence se doit d'en donner des
définitions, c'est évident.
Autre exemple : dans le § 5.5 sur les enumérations justement, ils ne
donnent AUCUN exemple d'une contruction d'une déclaration anonyme
d'énumération, un truc du genre :
enum {VRAI, FAUX};
eux systématiquement, ils écrivent
enum nonyme {VRAI, FAUX};
La norme, elle, donne des exemples pensés, et, ELLE, donne un tel
exemple. Or si je n'ai aucun exemple de certaines constructions (en plus
ici relativement usuelles), je ne vois pas comment je vais penser à les
utiliser à moins que je ne décide de déchiffrer la grammaire BNS du
langage C (ce qui est la présentation faite par HS et qu'ils
n'expliquent jamais, comme si tous les programmeurs de C connaissaient
la forme BNS d'une grammaire).
Et je pourrais multiplier les exemples où la norme est plus claire et
plus satisfaisante que HS.C'est une preuve d'honnêteté de la part des auteurs. D'autres, moins
scrupuleux, laissent leurs erreurs traîner de version en version...
En effet mais je m'étonne qu'à la 5ème édition, il en reste autant.
Le K&R est anti-pédagogique !
Il m'est arrivé plusieurs fois de préconiser aux participants d'un
cours sur le langage C de mettre ce livre à la poubelle. C'est un des
plus mauvais sur le langage (pour l'apprentissage, je préfère le
Harbison et Steele, c'est peu dire...)
Je n'aime pas trop le K&R car il m'a fait beaucoup souffrir. Mais plus
je connais le C plus je trouve que le livre a des qualités de synthèse.
Et du beau code bien concis.
J'aimais bien le bouquin de Philippe Drix : langage C, norme ANSI,
sous-titré, vers une approche objet.
J'ai beaucoup aimé ce livre même s'il n'est pas si facile à lire. Et il
m'a aidé à fixer pas mal de choses.
Wykaaa a écrit :
Ta phrase tendrait à dire, par analogie, que tu es plus intéressé par
l'apprentissage du dictionnaire et de la grammaire française que par
l'écriture du français ??
Ça paraît bizarre...
Non, il y en a qui aiment écrire des romans, il y en a qui aiment les
lire, il y en a qui aiment les lire et les relire, il y en a qui aiment
les étudier. Ou si on veut être mauvaise langue, il y a les créateurs et
il y a les critiques.Pour moi :
- les macros-fonctions
- les chaînes de caractères avec cette stupidité du pour marquer la
fin de chaîne. Il aurait plutôt fallu faire comme en PL/1
- l'équivalence pointeur/tableau
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le trop grand nombre de conversions implicites
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
OK mais dans tout ça, il y a plein de choses incontournables,
l'équivalence tableau-pointeur on peut pas s'en passer (Marc parlait des
choses à ne pas utiliser) et avec lesquelles on apprend très bien à
vivre (et qui me manqueront peut-être quand j'apprendrai autre chose que
C).
(1) je comprends ce qu'il veut dire par ça. En clair, c'est quoi
l'avantage ? qu'on dispose de vraies variables ?
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
Je veux bien mais en quoi cela est-il la "traduction" de
(1) the values can be generated for you ?
(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.
Ouais. Cette phrase est bizarre mais il y en a plein des comme ça dans
leur bouquin et ça reflète bien leur esprit assez tordu, il faut le
dire...
Esprit tordu ? Non, je ne pense pas, plutôt esprit malin, tellement
malin que leur livre est incompréhensible (sauf par certains esprits
avancés dont il existe ici quelques spécimens) par le débutant. Ils sont
tellement le langage dans la peau qu'il ne réalisent pas la polysémie de
certaines de leurs phrases.
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de
programmeurs C qui maîtrisent totalement le langage (et encore).
Et si c'était tout simplement parce que la doc est mal faite ?
Wykaaa a écrit :
Ta phrase tendrait à dire, par analogie, que tu es plus intéressé par
l'apprentissage du dictionnaire et de la grammaire française que par
l'écriture du français ??
Ça paraît bizarre...
Non, il y en a qui aiment écrire des romans, il y en a qui aiment les
lire, il y en a qui aiment les lire et les relire, il y en a qui aiment
les étudier. Ou si on veut être mauvaise langue, il y a les créateurs et
il y a les critiques.
Pour moi :
- les macros-fonctions
- les chaînes de caractères avec cette stupidité du pour marquer la
fin de chaîne. Il aurait plutôt fallu faire comme en PL/1
- l'équivalence pointeur/tableau
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le trop grand nombre de conversions implicites
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
OK mais dans tout ça, il y a plein de choses incontournables,
l'équivalence tableau-pointeur on peut pas s'en passer (Marc parlait des
choses à ne pas utiliser) et avec lesquelles on apprend très bien à
vivre (et qui me manqueront peut-être quand j'apprendrai autre chose que
C).
(1) je comprends ce qu'il veut dire par ça. En clair, c'est quoi
l'avantage ? qu'on dispose de vraies variables ?
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
Je veux bien mais en quoi cela est-il la "traduction" de
(1) the values can be generated for you ?
(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.
Ouais. Cette phrase est bizarre mais il y en a plein des comme ça dans
leur bouquin et ça reflète bien leur esprit assez tordu, il faut le
dire...
Esprit tordu ? Non, je ne pense pas, plutôt esprit malin, tellement
malin que leur livre est incompréhensible (sauf par certains esprits
avancés dont il existe ici quelques spécimens) par le débutant. Ils sont
tellement le langage dans la peau qu'il ne réalisent pas la polysémie de
certaines de leurs phrases.
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de
programmeurs C qui maîtrisent totalement le langage (et encore).
Et si c'était tout simplement parce que la doc est mal faite ?
Wykaaa a écrit :
Ta phrase tendrait à dire, par analogie, que tu es plus intéressé par
l'apprentissage du dictionnaire et de la grammaire française que par
l'écriture du français ??
Ça paraît bizarre...
Non, il y en a qui aiment écrire des romans, il y en a qui aiment les
lire, il y en a qui aiment les lire et les relire, il y en a qui aiment
les étudier. Ou si on veut être mauvaise langue, il y a les créateurs et
il y a les critiques.Pour moi :
- les macros-fonctions
- les chaînes de caractères avec cette stupidité du pour marquer la
fin de chaîne. Il aurait plutôt fallu faire comme en PL/1
- l'équivalence pointeur/tableau
- la structure de bloc qui est bancale (on ne peut pas définir de
fonction à l'intérieur d'une fonction). Il n'y a donc pas de notion de
fonction locale (il n'y a que la notion de fonction statique...)
- le trop grand nombre de conversions implicites
- le typedef qui introduit une liaison forte entre les niveaux lexical
et syntaxique et qui n'est pas du "vrai" typage mais seulement de
l'homonymie.
OK mais dans tout ça, il y a plein de choses incontournables,
l'équivalence tableau-pointeur on peut pas s'en passer (Marc parlait des
choses à ne pas utiliser) et avec lesquelles on apprend très bien à
vivre (et qui me manqueront peut-être quand j'apprendrai autre chose que
C).
(1) je comprends ce qu'il veut dire par ça. En clair, c'est quoi
l'avantage ? qu'on dispose de vraies variables ?
Un type enum est un ... type. #define n'indique aucun type pour un nom
et ce n'est pas une variable... (aucun contrôle ne peut être effectué
par le compilateur).
Je veux bien mais en quoi cela est-il la "traduction" de
(1) the values can be generated for you ?
(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.
Ouais. Cette phrase est bizarre mais il y en a plein des comme ça dans
leur bouquin et ça reflète bien leur esprit assez tordu, il faut le
dire...
Esprit tordu ? Non, je ne pense pas, plutôt esprit malin, tellement
malin que leur livre est incompréhensible (sauf par certains esprits
avancés dont il existe ici quelques spécimens) par le débutant. Ils sont
tellement le langage dans la peau qu'il ne réalisent pas la polysémie de
certaines de leurs phrases.
avant vers du code plus sécurisé. Cependant, écrire du code fiable de
bout en bout en C me paraît seulement à la portée des 5% de
programmeurs C qui maîtrisent totalement le langage (et encore).
Et si c'était tout simplement parce que la doc est mal faite ?
Wykaaa a écrit :Tiens "enum statement" ? ça existe ça ? Ce serait pas plutôt "enum
declaration" ?
Cette confusion est habituelle chez K&R.
Ah bon ? confusion entre "statement" et "declaration" ou juste entre
"enum statement" etc "enum declaration" ? t'as un exemple précis ?
Wykaaa a écrit :
Tiens "enum statement" ? ça existe ça ? Ce serait pas plutôt "enum
declaration" ?
Cette confusion est habituelle chez K&R.
Ah bon ? confusion entre "statement" et "declaration" ou juste entre
"enum statement" etc "enum declaration" ? t'as un exemple précis ?
Wykaaa a écrit :Tiens "enum statement" ? ça existe ça ? Ce serait pas plutôt "enum
declaration" ?
Cette confusion est habituelle chez K&R.
Ah bon ? confusion entre "statement" et "declaration" ou juste entre
"enum statement" etc "enum declaration" ? t'as un exemple précis ?
candide, le 03/07/2008 a écrit :Bonjour,
Bonjour
[...]Si, par exemple
enum toto {A4, BQ} t;
peut-on écrire
t(;
Oui et non.
Oui parce que ça compilera. Le seul risque est de passer pour un idiot à
la relecture, ou de faire sombrer le relecteur dans des abîmes de
perplexité s'il cherche à comprendre quelque chose.
Non parce que une obfuscation sans intérêt est simplement une erreur. De
plus ce code est certainement en désaccord avec toutes les règles de
style, et que violer une règle de style est une erreur.
Notez que la valeur n'a rien à voir. tQ serait peut-être encore plus
mauvais.
Bien entendu, le compilateur est à mon sens autorisé à warner, et un
lint quelconque à vous châtier.(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;
?
Les valeurs négatives sont valides dans les enum. Et au passage rien
n'impose, sauf à respecter des règles de style, l'absence de doublons
implicites ou explicites:
enum toto {A = 34, B = 33, B1, C = 34, D = -1000} t;
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 ?
Oublier un peu la norme et la littérature et se fixer des règles de bons
sens. Les enum ne sont jamais indispensables, et directement
intéressantes essentiellement en liaison avec un switch...case (et à mon
avis c'est tout à fait réciproque). Et dans quelques cas déterminés par
le fait que la valeur sous-jacente des termes de l'enum ne doit pas
importer du tout, comme pour le switch...case. On s'imposera alors les
règles:
- Laisser l'enum se démerder, donc ne pas utiliser le forçage de valeurs.
- Ne jamais présumer ni même tenir compte de la valeur numérique d'une
variable du type de l'enum. A une exception, si on ne fait pas de
forçage, on peut utiliser l'ordre dans lequel on a initialisé l'enum et
donc faire des comparaisons entre variables du même type enum.
- Ne jamais utiliser autre chose que des termes de l'enum, donc jamais
de valeurs numériques, dans le switch...case, ou un tableau, si on
décide de l'indicer par l'enum. Pas de résultats d'opérations entre des
variables de type de l'enum, ces résultats n'étant d'ailleurs pas dans
l'enum à priori.
Un exemple, en sachant qu'une structure serait sans doute plus adaptée:
enum{
COTE_FENETRE,
NB_FENTRES,
HAUTEUR_FENETRE,
LARGEUR_FENETRE,
UNUSED_SIZE_ELEM
};
unsigned long GEOMETRIE[UNUSED_SIZE_ELEM];
Je ne mets pas de cast sur UNUSED_SIZE_ELEM, je n'en vois pas l'utilité.
On va pouvoir utiliser des trucs comme GEOMETRIE[HAUTEUR_FENETRE],
supposés être lisibles. Si on n'utilise jamais autre chose qu'un membre
de l'enum pour indicer GEOMETRIE, on peut en cours du développement sans
souci réordonner le machin, insérer de nouveau membres où bon nous
semble, et supprimer des membres de l'enum. Dans ce dernier cas, si on
continue à l'utiliser à un endroit, on aura une erreur.
Il y a un cas qui fait exception à toutes ces règles, et qui est
peut-être envisagé dans la norme. Ce sont les enum composées de valeurs
entières avec un seul bit allumé. On pourra s'autoriser une mise en OU,
pour ensuite faire une lecture par masquage par les éléments de l'enum.
Il faudra quand même être prudent, la taille exigée monte très vite.Ainsi dans mon premier exemple ci-dessus, dois-je écrire
t=(enum toto) 28;
?
??
A mon avis, ce qui est suggéré ici est que: imaginons qu'on soit
pragmatique et dans une République idéale sans la double Corse 2A 2B.
Nous pourrions penser nous simplifier la vie avec une enum des noms de
départements en correspondance avec leurs numéros. Nous obtiendrions
celà en copiant-collant une liste, puis en forçain AIN à 1, et
GUADELOUPE à 971. Je ne le ferais pas, sauf pour un programme jetable,
mais peu importe.
Maintenant nous voulons obtenir la chaîne "01" à partir de AIN, valeur
1. Alors, le texte suggère d'utiliser (int)AIN dans le ?printf().
Ou pour tester si un département est un DOM (comme la Corse ?), faire:
isDom(int dep){
return dep >= (int)GUADELOUPE && dep <= (int)LA_REUNION;
}
Tout celà fonctionnerait sans le cast, mais c'est certainement correct
de le systématiser.
candide, le 03/07/2008 a écrit :
Bonjour,
Bonjour
[...]
Si, par exemple
enum toto {A4, BQ} t;
peut-on écrire
t(;
Oui et non.
Oui parce que ça compilera. Le seul risque est de passer pour un idiot à
la relecture, ou de faire sombrer le relecteur dans des abîmes de
perplexité s'il cherche à comprendre quelque chose.
Non parce que une obfuscation sans intérêt est simplement une erreur. De
plus ce code est certainement en désaccord avec toutes les règles de
style, et que violer une règle de style est une erreur.
Notez que la valeur n'a rien à voir. tQ serait peut-être encore plus
mauvais.
Bien entendu, le compilateur est à mon sens autorisé à warner, et un
lint quelconque à vous châtier.
(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;
?
Les valeurs négatives sont valides dans les enum. Et au passage rien
n'impose, sauf à respecter des règles de style, l'absence de doublons
implicites ou explicites:
enum toto {A = 34, B = 33, B1, C = 34, D = -1000} t;
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 ?
Oublier un peu la norme et la littérature et se fixer des règles de bons
sens. Les enum ne sont jamais indispensables, et directement
intéressantes essentiellement en liaison avec un switch...case (et à mon
avis c'est tout à fait réciproque). Et dans quelques cas déterminés par
le fait que la valeur sous-jacente des termes de l'enum ne doit pas
importer du tout, comme pour le switch...case. On s'imposera alors les
règles:
- Laisser l'enum se démerder, donc ne pas utiliser le forçage de valeurs.
- Ne jamais présumer ni même tenir compte de la valeur numérique d'une
variable du type de l'enum. A une exception, si on ne fait pas de
forçage, on peut utiliser l'ordre dans lequel on a initialisé l'enum et
donc faire des comparaisons entre variables du même type enum.
- Ne jamais utiliser autre chose que des termes de l'enum, donc jamais
de valeurs numériques, dans le switch...case, ou un tableau, si on
décide de l'indicer par l'enum. Pas de résultats d'opérations entre des
variables de type de l'enum, ces résultats n'étant d'ailleurs pas dans
l'enum à priori.
Un exemple, en sachant qu'une structure serait sans doute plus adaptée:
enum{
COTE_FENETRE,
NB_FENTRES,
HAUTEUR_FENETRE,
LARGEUR_FENETRE,
UNUSED_SIZE_ELEM
};
unsigned long GEOMETRIE[UNUSED_SIZE_ELEM];
Je ne mets pas de cast sur UNUSED_SIZE_ELEM, je n'en vois pas l'utilité.
On va pouvoir utiliser des trucs comme GEOMETRIE[HAUTEUR_FENETRE],
supposés être lisibles. Si on n'utilise jamais autre chose qu'un membre
de l'enum pour indicer GEOMETRIE, on peut en cours du développement sans
souci réordonner le machin, insérer de nouveau membres où bon nous
semble, et supprimer des membres de l'enum. Dans ce dernier cas, si on
continue à l'utiliser à un endroit, on aura une erreur.
Il y a un cas qui fait exception à toutes ces règles, et qui est
peut-être envisagé dans la norme. Ce sont les enum composées de valeurs
entières avec un seul bit allumé. On pourra s'autoriser une mise en OU,
pour ensuite faire une lecture par masquage par les éléments de l'enum.
Il faudra quand même être prudent, la taille exigée monte très vite.
Ainsi dans mon premier exemple ci-dessus, dois-je écrire
t=(enum toto) 28;
?
??
A mon avis, ce qui est suggéré ici est que: imaginons qu'on soit
pragmatique et dans une République idéale sans la double Corse 2A 2B.
Nous pourrions penser nous simplifier la vie avec une enum des noms de
départements en correspondance avec leurs numéros. Nous obtiendrions
celà en copiant-collant une liste, puis en forçain AIN à 1, et
GUADELOUPE à 971. Je ne le ferais pas, sauf pour un programme jetable,
mais peu importe.
Maintenant nous voulons obtenir la chaîne "01" à partir de AIN, valeur
1. Alors, le texte suggère d'utiliser (int)AIN dans le ?printf().
Ou pour tester si un département est un DOM (comme la Corse ?), faire:
isDom(int dep){
return dep >= (int)GUADELOUPE && dep <= (int)LA_REUNION;
}
Tout celà fonctionnerait sans le cast, mais c'est certainement correct
de le systématiser.
candide, le 03/07/2008 a écrit :Bonjour,
Bonjour
[...]Si, par exemple
enum toto {A4, BQ} t;
peut-on écrire
t(;
Oui et non.
Oui parce que ça compilera. Le seul risque est de passer pour un idiot à
la relecture, ou de faire sombrer le relecteur dans des abîmes de
perplexité s'il cherche à comprendre quelque chose.
Non parce que une obfuscation sans intérêt est simplement une erreur. De
plus ce code est certainement en désaccord avec toutes les règles de
style, et que violer une règle de style est une erreur.
Notez que la valeur n'a rien à voir. tQ serait peut-être encore plus
mauvais.
Bien entendu, le compilateur est à mon sens autorisé à warner, et un
lint quelconque à vous châtier.(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;
?
Les valeurs négatives sont valides dans les enum. Et au passage rien
n'impose, sauf à respecter des règles de style, l'absence de doublons
implicites ou explicites:
enum toto {A = 34, B = 33, B1, C = 34, D = -1000} t;
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 ?
Oublier un peu la norme et la littérature et se fixer des règles de bons
sens. Les enum ne sont jamais indispensables, et directement
intéressantes essentiellement en liaison avec un switch...case (et à mon
avis c'est tout à fait réciproque). Et dans quelques cas déterminés par
le fait que la valeur sous-jacente des termes de l'enum ne doit pas
importer du tout, comme pour le switch...case. On s'imposera alors les
règles:
- Laisser l'enum se démerder, donc ne pas utiliser le forçage de valeurs.
- Ne jamais présumer ni même tenir compte de la valeur numérique d'une
variable du type de l'enum. A une exception, si on ne fait pas de
forçage, on peut utiliser l'ordre dans lequel on a initialisé l'enum et
donc faire des comparaisons entre variables du même type enum.
- Ne jamais utiliser autre chose que des termes de l'enum, donc jamais
de valeurs numériques, dans le switch...case, ou un tableau, si on
décide de l'indicer par l'enum. Pas de résultats d'opérations entre des
variables de type de l'enum, ces résultats n'étant d'ailleurs pas dans
l'enum à priori.
Un exemple, en sachant qu'une structure serait sans doute plus adaptée:
enum{
COTE_FENETRE,
NB_FENTRES,
HAUTEUR_FENETRE,
LARGEUR_FENETRE,
UNUSED_SIZE_ELEM
};
unsigned long GEOMETRIE[UNUSED_SIZE_ELEM];
Je ne mets pas de cast sur UNUSED_SIZE_ELEM, je n'en vois pas l'utilité.
On va pouvoir utiliser des trucs comme GEOMETRIE[HAUTEUR_FENETRE],
supposés être lisibles. Si on n'utilise jamais autre chose qu'un membre
de l'enum pour indicer GEOMETRIE, on peut en cours du développement sans
souci réordonner le machin, insérer de nouveau membres où bon nous
semble, et supprimer des membres de l'enum. Dans ce dernier cas, si on
continue à l'utiliser à un endroit, on aura une erreur.
Il y a un cas qui fait exception à toutes ces règles, et qui est
peut-être envisagé dans la norme. Ce sont les enum composées de valeurs
entières avec un seul bit allumé. On pourra s'autoriser une mise en OU,
pour ensuite faire une lecture par masquage par les éléments de l'enum.
Il faudra quand même être prudent, la taille exigée monte très vite.Ainsi dans mon premier exemple ci-dessus, dois-je écrire
t=(enum toto) 28;
?
??
A mon avis, ce qui est suggéré ici est que: imaginons qu'on soit
pragmatique et dans une République idéale sans la double Corse 2A 2B.
Nous pourrions penser nous simplifier la vie avec une enum des noms de
départements en correspondance avec leurs numéros. Nous obtiendrions
celà en copiant-collant une liste, puis en forçain AIN à 1, et
GUADELOUPE à 971. Je ne le ferais pas, sauf pour un programme jetable,
mais peu importe.
Maintenant nous voulons obtenir la chaîne "01" à partir de AIN, valeur
1. Alors, le texte suggère d'utiliser (int)AIN dans le ?printf().
Ou pour tester si un département est un DOM (comme la Corse ?), faire:
isDom(int dep){
return dep >= (int)GUADELOUPE && dep <= (int)LA_REUNION;
}
Tout celà fonctionnerait sans le cast, mais c'est certainement correct
de le systématiser.
In article <487145fa$0$900$,
Wykaaa wrote:- Les enum doivent être utilisés conjointement avec switch.
Marrant, j'ai tendance a bannir switch de mon code.
In article <487145fa$0$900$ba4acef3@news.orange.fr>,
Wykaaa <wykaaa@yahoo.fr> wrote:
- Les enum doivent être utilisés conjointement avec switch.
Marrant, j'ai tendance a bannir switch de mon code.
In article <487145fa$0$900$,
Wykaaa wrote:- Les enum doivent être utilisés conjointement avec switch.
Marrant, j'ai tendance a bannir switch de mon code.
Bien sûr que si qu'on peut se passer de l'équivalence pointeur/tableau
en C. Il suffit de programmer proprement.
C'est K&R qui font croire qu'on ne peut s'en passer...
Bien sûr que si qu'on peut se passer de l'équivalence pointeur/tableau
en C. Il suffit de programmer proprement.
C'est K&R qui font croire qu'on ne peut s'en passer...
Bien sûr que si qu'on peut se passer de l'équivalence pointeur/tableau
en C. Il suffit de programmer proprement.
C'est K&R qui font croire qu'on ne peut s'en passer...