lucas-84 | Merci encore une fois pour ta réponse. Citation :
Ça n'a pas grand intérêt sauf éventuellement, à indiquer explicitement à un outil, qui devrait être paramétrable afin de ne pas se préoccuper de ce genre de chose, qu'on ne se préoccupe pas de la valeur de retour. Bref, ça me semble plus être la règle posée pour faire plaisir à un outil et son concepteur qu'autre chose. Dans la pratique, on ne rencontre pas ce style de cast dans du code C habituellement. Elle est pas complètement idiote donc cette règle, mais comme elle ne fait pas partie des usages, elle risque plus de déconcerter quelqu'un qui relira le code qu'autre chose.
|
Si on gagne en lisibilité, je m'avoue vaincu. Mais bon, avec splint : Citation :
file.c:149:3: Return value (type int) ignored: fputs(s, f) Result returned by function call is not used. If this is intended, can cast result to (void) to eliminate message. (Use -retvalint to inhibit warning)
|
Citation :
On n’exécute la condition qu'une fois, alors c'est moins important, mais ça peut être préférable. Mais en fait, l'intérêt de ce style, c'est le suivant: Quand on a: int (ou char) machin = f(blabla); if (test sur machin) { bloc (ou on n'utilise pas machin) } On peut le remplacer par if (f(blabla)) { bloc } parce que ça évite une variable inutile. Idem quand on a: int (ou char) machin = f(blabla); while (test sur machin) { bloc (ou on n'utilise pas machin, sauf une fois, pour avoir une nouvelle valeur de test, en faisant machin = f(blabla)) } On peut le remplacer par ça se remplace par while (f(blabla)) { bloc } Par contre, a partir du moment ou on utilise la valeur testée dans le bloc, on ne gagne rien a utiliser ce style de codage (peut être quelques octets dans l'exécutable généré), et on rend la lecture moins claire.
|
Après réflexion, je suis tout à fait d'accord. Citation :
Un (bon) programmeur sait à quoi correspond getopt_long, donc il comprends le sens de ce code. Mais dès que cela devient trop complexe à lire sans perdre le fil du code courant, il vaut mieux éviter, car c'est mauvais pour la maintenance du code. Un autre point: FILE *f = NULL; Il vaut mieux éviter d'affecter a NULL un pointeur déclaré, car alors, le compilateur n'émettra plus les warnings qu'il émet quand un pointeur est utilisé avant d'avoir été affecté, puisque maintenant pour lui, le pointeur a été affecté avant première utilisation, et ça, c'est le genre de warning très utile. (l'inconvénient c'est que si dans une fonction, on renvoie un pointeur sans l'avoir affecté, la fonction appelante ne peut pas vérifier qu'il n'y a pas eu affectation, mais dans la pratique je préfère ce cas de figure, car quand je récupère un pointeur d'une fonction appellée, je vais relire son code pour vérifier qu'il y a bien eu affectation avant retour de la fonction).
|
Je prends note, c'est très intéressant. Sinon, j'essaie en ce moment de décortiquer une suite de messages de splint : Spoiler :
splint file.c Splint 3.1.2 --- 03 May 2009 file.c: (in function open_file) file.c:35:12: Dependent storage f returned as implicitly only: f Dependent storage is transferred to a non-dependent reference. (Use -dependenttrans to inhibit warning) file.c:30:34: Storage f becomes dependent file.c: (in function create_file) file.c:67:24: Fresh storage f not released before return A memory leak has been detected. Storage allocated locally is not released before the last reference to it is lost. (Use -mustfreefresh to inhibit warning) file.c:64:37: Fresh storage f created file.c: (in function read_file) file.c:91:24: Fresh storage f not released before return file.c:82:37: Fresh storage f created file.c: (in function write_file) file.c:114:6: Return value (type int) ignored: fputs(s, f) Result returned by function call is not used. If this is intended, can cast result to (void) to eliminate message. (Use -retvalint to inhibit warning) file.c:116:24: Fresh storage f not released before return file.c:106:37: Fresh storage f created |
D'après ce que j'ai déchiffré rapidement, on dirait qu'il ne détecte pas le fclose et donc la libération de la mémoire. Il me parle de memory leak, mais après avoir passé un coup de valgrind, je n'en vois aucune. Mon file.c : Code :
- /**
- * \file file.c
- * \brief manipule les fichiers
- * \author lucas-84
- * \version V0.2 on 25/10/2011
- * \date 24/10/2011
- *
- * Manipule les fichiers directement
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "error.h"
- #include "file.h"
- /**
- * \fn static ret_e open_file (const char *path, const char *mode)
- * \brief Ouvre un fichier
- *
- * \param path pointeur vers une chaine de caractere indiquant le chemin du
- * fichier a creer.
- * \param mode pointeur vers une chaine de caractere indiquant le mode
- * d'ouverture du fichier a creer.
- * \return NULL en cas d'erreur, le fichier ouvert sinon.
- */
- /*@null@*/ static FILE *open_file (const char *path, const char *mode)
- {
- FILE *f = fopen (path, mode);
- if (f == NULL) {
- PRINT_ERROR ("fopen" );
- }
- return f;
- }
- /**
- * \fn static ret_e close_file (FILE *f)
- * \brief Ferme un fichier
- *
- * \param f fichier a fermer.
- * \return RET_ERROR en cas d'erreur, RET_SUCCESS sinon.
- */
- static ret_e close_file (FILE *f)
- {
- if (fclose (f) == EOF) {
- PRINT_ERROR ("fclose" );
- return RET_ERROR;
- }
- return RET_SUCCESS;
- }
- /**
- * \fn ret_e create_file (const char *path)
- * \brief Cree un fichier
- *
- * \param path pointeur vers une chaine de caractere indiquant le chemin du
- * fichier a creer.
- * \return RET_ERROR en cas d'erreur, RET_SUCCESS sinon.
- */
- ret_e create_file (const char *path)
- {
- FILE *f = open_file (path, "w" );
- if (f != NULL) {
- return close_file (f);
- }
- return RET_ERROR;
- }
- /**
- * \fn ret_e read_file (const char *path)
- * \brief Lit un fichier
- *
- * \param path pointeur vers une chaine de caractere indiquant le chemin du
- * fichier a creer.
- * \return RET_ERROR en cas d'erreur, RET_SUCCESS sinon.
- */
- ret_e read_file (const char *path)
- {
- FILE *f = open_file (path, "r" );
- if (f != NULL) {
- int c = fgetc (stdin);
- while (c != EOF) {
- fprintf (stdout, "%c", c);
- c = fgetc (stdin);
- }
- return close_file (f);
- }
- return RET_ERROR;
- }
- /**
- * \fn ret_e write_file (const char *path)
- * \brief Ecrit un fichier
- *
- * \param path pointeur vers une chaine de caractere indiquant le chemin du
- * fichier a creer.
- * \return RET_ERROR en cas d'erreur, RET_SUCCESS sinon.
- */
- ret_e write_file (const char *path)
- {
- FILE *f = open_file (path, "a" );
- if (f != NULL) {
- char s[LINE_MAX] = "";
- fprintf (stdout, "\"/quit\" to stop\n" );
- while (fgets (s, (int) sizeof (s), stdin) != NULL &&
- strstr (s, "/quit" ) == 0) {
- fputs (s, f);
- }
- return close_file (f);
- }
- return RET_ERROR;
- }
| Merci à tous ! Bonne journée, lucas-84 Message édité par lucas-84 le 25-10-2011 à 14:17:17
|