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

[débutant] 1er programme, j'aimerais vos commentaires.

91 réponses
Avatar
Beware
Bonjour,

D=E9butant dans l'apprentissage du langage C, j'ai cr=E9e un petit
programme, un jeu du pendu. Le jeu =E0 l'air de fonctionner. Je dis
"l'air de", car il est probable qu'il reste des bugs que je dois
corriger.
Cependant ce n'est pas l'objet de ma question. En effet, dans un souci
de m'am=E9liorer je d=E9sirerais avoir les commentaires de personnes
connaissant et maitrisant mieux le langage C que moi.

Les fichiers du programme (main.c, pendu.h et dico.txt) sont
disponible ici :
http://beware007.free.fr/Projet_C/Pendu/


Merci d'avance pour votre aide, vos commentaire et critiques.

10 réponses

1 2 3 4 5
Avatar
Eric Levenez
Le 14/03/09 20:51, dans <49bc0ab4$0$2685$, « Alexandre
BACQUART » a écrit :

Eric Levenez wrote:
Apres, on peut militer pour l'amelioration de gcc... entre autres le
rajout d'intelligence dans le compilateur pour eliminer les warnings
debiles...



Je considère que les warnings sur les signés/non signés ne sont pas débiles
et doivent être traités et non ignorés.



C'est juste, mais comme le dit Marc, le cast ne "traite" pas, il fait
taire le compilateur, c'est très différent. Mais dans des cas comme
celui-là, avec des tailles si petites, on voit difficilement quel genre
de problème pourrait survenir à convertir un signé en non-signé.



Oui, mais si on ne corrige pas le warning (c'est plus politiquement correct
que "traiter" ?), comment retrouver les warnings à corriger car dangereux,
de ceux qui ne le sont pas, comme avec le code posté ? En mettant une limite
au nombre de warnings "acceptables" avant de "s'affoler" ?

--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
Antoine Leca
Le 14/03/2009 9:47, candide écrivit :
printf( "nt Vous avez perdu. Le mot a trouver etait : %s",
On peut utiliser sans souci les accents dans les messages (sauf si on
s'appelle Marc E. et que l'on travaille sur des terminaux zarbi), c'est
quand même plus lisible.



Avec la console Windows vaut mieux s'abstenir des accents.



Voilà une drôle de remarque ! À quoi est-elle due ? Aurais-tu des
problèmes d'affichage en console Windows d'un programme ? Est-ce que
cela viendrait-il d'un compilateur en particulier ?

Et si tu compiles sous Linux avec un locale (précisant un certain
encodage) donné, puis que tu changes de locale (avec un *autre*
encodage), est-ce que le programme affiche correctement les accents ?


Antoine
Avatar
Beware
On 14 mar, 22:30, Antoine Leca wrote:
Le 14/03/2009 9:47, candide écrivit :

>>     printf( "nt Vous avez perdu. Le mot a trouver etait : %s",
>> On peut utiliser sans souci les accents dans les messages (sauf si on
>> s'appelle Marc E. et que l'on travaille sur des terminaux zarbi), c'es t
>> quand même plus lisible.

> Avec la console Windows vaut mieux s'abstenir des accents.

Voilà une drôle de remarque ! À quoi est-elle due ? Aurais-tu des
problèmes d'affichage en console Windows d'un programme ? Est-ce que
cela viendrait-il d'un compilateur en particulier ?

Et si tu compiles sous Linux avec un locale (précisant un certain
encodage) donné, puis que tu changes de locale (avec un *autre*
encodage), est-ce que le programme affiche correctement les accents ?

Antoine




En tout, j'ai supprime les accents dans mes messages car sinon il
affiche de mauvais caractére.

Pour le reste, ne croyez pas que je bosse pas, j'ai passé une grande
partie de la journée a modifier mon code. Et j'ai fait beaucoup de
modification (utiles j'espére). Mais comme j'ai pas encore vérifier et
mis en pratique tout vos conseils, je ne poste pas encore le nouveau
code.
Avatar
Antoine Leca
Le 14/03/2009 12:36, Eric Levenez écrivit :
Le 14/03/09 10:47, dans <49bb7d46$0$21963$,
« candide » a écrit :

Eric Levenez a écrit :

Il conviendrait de corriger ces warnings qui peuvent masquer des problèmes
car size_t est non signé et cela peut entraîner des problèmes dans d'autres
programmes.


Et tu recommandes quoi ? Ne pas utiliser size_t ou caster en int (par exemple)
ou autre chose encore ?



Comme strlen retourne un nombre >= 0, je "casterais" en int le code de
retour de strlen.



Le contexte:
while (indice_tableau < strlen(motSecret)) {

Ne pas utiliser size_t revient à ne pas utiliser strlen(), cela paraît
impossible, ou à tout le moins un étrange conseil (cela revient à devoir
réécrire toute la bibliothèque standard avec un nouveau jeu de valeurs ;
notons que c'est le propos de certains...)


Supposons maintenant que motSecret soit de 40000 octets, en size_t il
n'y a pas de problème, le malloc réussit (on suppose) ; puis on
travaille avec l'indice signé, après 32767 il devient négatif.

Sans transtypage, le programme continue à claudiquer (comparaison
signé-non signé, le signé est convertit).
Avec transtypage, le résultat de strlen() devient négatif, le programme
ne marche plus du tout.

Dans tous les cas, il y a un problème, donc l'avertissement est justifié.


Si tu veux programmer de manière à éliminer les avertos (et sans
utiliser size_t ni pointeurs, ce qui serait probablement plus indiqué),
ici on peut définir une variable
int taille_de_motSecret;
et la renseigner (avec contrôle de domaine) au moment où est créé
motSecret, et ensuite utiliser cette variable, ce qui ne devrait pas
créer d'avertissement.

Après, si pour le code
int taille;
/* ... */
size_t t = strlen(machine);
if( t < INT_MAX )
taille = t;
else AU_SECOURS(...);
le compilateur continue d'envoyer des avertos signé/non signé, cela
devient désespérant...


Par ailleurs, ici le mélange de types entre int et size_t revient pour
vous à un mélange entre int32_t et uint32_t, donc soulève les questions
signé/non signé. Mais que ce passerait-il si size_t avait une magnitude
supérieure ou inférieure à int ?


Antoine
Avatar
Antoine Leca
Le 14/03/2009 13:28, Eric Levenez écrivit :
Le 14/03/09 14:14, dans <gpgair$eo2$, « Marc Espie »
Ignorer l'avertissement et envoyer gcc se faire cuire un oeuf.



Je ne pense pas que ce conseil soit adapté. Comment filtrer les warnings à
traiter de ceux à ignorer ?



Pour ce faire, il y a un truc que j'aime bien et que je ne retrouve pas
dans tous les compilos, c'est la possibilité (d'habitude avec un
commentaire avec un format spécial, parfois un #pragma) de faire taire
le compilateur sur une ligne donnée pour un avertissement donné.
L'un des plus classique, c'est ARGUSED avec toutes ses variations.

L'avantage, c'est que le commentaire-qui-tue est un traitement passif,
sans effet secondaire, par rapport au transtypage qui fait taire qui lui
peut avoir des effets induits sur le code (et en général, lorsque le
compilateur rajoute du code alors que le programmeur veut faire taire un
avertissement, le bogue n'est pas loin...)


Antoine
Avatar
Alexandre BACQUART
Eric Levenez wrote:
Le 14/03/09 20:51, dans <49bc0ab4$0$2685$, « Alexandre
BACQUART » a écrit :

Eric Levenez wrote:
Apres, on peut militer pour l'amelioration de gcc... entre autres le
rajout d'intelligence dans le compilateur pour eliminer les warnings
debiles...


Je considère que les warnings sur les signés/non signés ne sont pas débiles
et doivent être traités et non ignorés.


C'est juste, mais comme le dit Marc, le cast ne "traite" pas, il fait
taire le compilateur, c'est très différent. Mais dans des cas comme
celui-là, avec des tailles si petites, on voit difficilement quel genre
de problème pourrait survenir à convertir un signé en non-signé.



Oui, mais si on ne corrige pas le warning (c'est plus politiquement correct
que "traiter" ?), comment retrouver les warnings à corriger car dangereux,
de ceux qui ne le sont pas, comme avec le code posté ? En mettant une limite
au nombre de warnings "acceptables" avant de "s'affoler" ?



Ho mais moi je suis d'accord pour le cast et faire taire le compilo dans
ce cas.

Mais il faut nuancer la remarque de... Marc. S'il ne s'agit que de
maintenir son propre bout de code le temps d'une session de travail, il
a raison et quelques warnings qui traînent sont mieux que rien.

Après, lorsqu'il s'agit de le poster (sauf dans le but d'apprendre
bien-sûr) ou de le mettre à jour sur une base, il est de bon ton de
supprimer tous les warning. Dans le cas de strlen(), on peut caster
size_t en int sans peur et sans reproche AMHA (surtout si éviter le cast
signifie remplacer un signed flexible en un unsigned capricieux).

Si par grand malheur on est susceptible de traiter des chaînes plus
longues que min(INT_MAX, SIZE_MAX) (qui a ma connaissance n'a aucune
chance d'être < 32767), on a besoin d'un truc plus robuste que strlen()
et/ou int.


--
Alex
Avatar
Antoine Leca
Le 14/03/2009 16:22, candide écrivit :
Concernant -pedantic, je trouve qu'il n'est pas évident de savoir quel est son
rôle exact, d'après la doc de gcc, -pedantic avertit chaque fois que la Norme
exige un "diagnostic" :



Ce n'est pas la vraie raison !
En fait, pedantic active les avertissements requis par la norme mais que
les auteurs de GCC considèrent nuisibles ou inutiles.
(-pedantic a ou avait aussi un effet sur les trigraphes, avec la même
analyse, l'un des auteurs de GCC ayant du haut du clavier de son VT-100
américain considéré manifestement qu'il s'agissait d'une mauvaise idée).


Je partage totalement ton avis. Quand j'ai commencé le C, je ne connaissais que
les int puis un jour je suis tombé sur size_t et adieu la simplicité. Puis je
suis tombé sur le recommandations dans ce forum concernant l'emploi de size_t
pour des tailles d'objets ou des indices de parcours de tableaux statiques ou
dynamiques. J'ai donc adopté size_t, Puis je suis tombé sur les problèmes de
conversion que tu signales avec les conséquences catastrophiques que cela peut
avoir. Depuis, je suis dans l'expectative, j'ai encore parcouru les archives de
fclc et clc il y a peu de temps à la recherche de la bonne attitude et de la
bonne recommandation.



Je crois qu'utiliser les pointeurs est souvent meilleur : en effet ces
derniers se comportent le plus souvent comme des non signés, _sauf_
lorsqu'on calcule la différence entre deux d'entre eux, car ptrdiff_t
est alors signé.

Cela n'est cependant pas la panacée, car d'une part rien ne précise les
relations entre int et ptrdiff_t, et d'autre part les normes n'assurent
pas que ptrdiff_t et ssize_t soit le même type...



Dans la grosse majorite des codes, l'introduction de size_t pour toutes
les tailles memoire est "absurde":





Sans vouloir paraphraser, il faut quand même remarquer que c'est surtout
le plus mauvais choix, à l'exception de tous les autres... autrement
dit, c'est le moins mauvais choix, utiliser d'autres types étant en
général encore plus "absurde".

Je concède qu'une autre façon de faire (qui me vient de K&R) pour les
programmes courants est d'utiliser systématiquement des int, d'ignorer
systématiquement les avertissements d'excès de domaine, et de se limiter
partout au domaine [0, INT_MAX]. Le hic, c'est bien sûr que l'on arrive
toujours au cas où INT_MAX est trop petit (taille des objets au temps du
16 bits ou pour les fichiers vidéo ou autres, le 2038 de la semaine
dernière, la société qui grandit et qui dépasse 220 millions de CA, etc.)


Antoine
Avatar
Alexandre BACQUART
Antoine Leca wrote:
Le 14/03/2009 9:47, candide écrivit :
printf( "nt Vous avez perdu. Le mot a trouver etait : %s",
On peut utiliser sans souci les accents dans les messages (sauf si on
s'appelle Marc E. et que l'on travaille sur des terminaux zarbi), c'est
quand même plus lisible.


Avec la console Windows vaut mieux s'abstenir des accents.



Voilà une drôle de remarque ! À quoi est-elle due ? Aurais-tu des
problèmes d'affichage en console Windows d'un programme ? Est-ce que
cela viendrait-il d'un compilateur en particulier ?



J'ai déjà eu ce problème dans de nombreux cas de développement. Mais
pour ma part, je suis configuré par défaut en anglais, peut-être que ça
joue. Je suppose que ça doit se configurer quelque-part pour que ce soit
spécifique à certains outils, mais ça ne me dérange pas suffisamment
pour que je cherche la manière de faire.


--
Alex
Avatar
Antoine Leca
Le 14/03/2009 22:21, Alexandre BACQUART écrivit :
min(INT_MAX, SIZE_MAX) (qui a ma connaissance n'a aucune
chance d'être < 32767)



En C90, size_t pouvait légalement être plus petit que 15 bits (pas
pratiquement, c'est peut-être ce que tu voulais dire).


Antoine
Avatar
Antoine Leca
Le 14/03/2009 22:50, Alexandre BACQUART écrivit :
Antoine Leca wrote:
Le 14/03/2009 9:47, candide écrivit :
printf( "nt Vous avez perdu. Le mot a trouver etait : %s",
On peut utiliser sans souci les accents dans les messages (sauf si on
s'appelle Marc E. et que l'on travaille sur des terminaux zarbi), c'est
quand même plus lisible.


Avec la console Windows vaut mieux s'abstenir des accents.



Voilà une drôle de remarque ! À quoi est-elle due ? Aurais-tu des
problèmes d'affichage en console Windows d'un programme ? Est-ce que
cela viendrait-il d'un compilateur en particulier ?



J'ai déjà eu ce problème dans de nombreux cas de développement. Mais
pour ma part, je suis configuré par défaut en anglais, peut-être que ça
joue. Je suppose que ça doit se configurer quelque-part pour que ce soit
spécifique à certains outils, mais ça ne me dérange pas suffisamment
pour que je cherche la manière de faire.



Premier résultat d'une recherche Google :
http://mail.nl.linux.org/linux-utf8/2004-11/msg00009.html, 1er alinéa

Évidemment, la valeur par défaut UTF-8 pour le jeu d'exécution est
inadaptée à Windows, mais comme il y a deux valeurs plausibles
(Windows-125x alias "Ansi" pour les programmes GUI et 85x alias "OEM"
pour la console), Mingw & co ont choisi la solution de facilité qui
consiste à ne pas choisir et garder la valeur par défaut, charge à
chacun de modifier son fichier specs ou ses options de compilation.


Antoine
1 2 3 4 5