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

Commentaires sur code source (long)

48 réponses
Avatar
Eddahbi Karim
Bonjour à tous,

J'suis rentré de vacanes et me revoici avec mes exos de C. Cette fois ci
crée une structure pour stocker les informations d'un vol.

Si vous avez tout commentaire sur le code, de manière à l'améliorer,
faites en part :-).

/*-8<-----------------------------------------------------------------

flight_reservation.c -- This program simulate a flight reservation

Author : Eddahbi Karim
E-mail : non.tu.ne.me.connais.pas.spavrai@ifrance.com Nick :
ThE_TemPLaR (newsgroups/Forums)

----------------------------------------------------------------------

Usage : Launch the program and enter the airport codes,
the flight number, the starting time and the arrival time.

Warning : Time must contain 2 digits : 2 digits. Not more, not
less.

----------------------------------------------------------------->8-*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

/*--------------------------------------------------------------------

USAGE : Calculate the first dimension of a two dimensions array

PARAMETER : Two dimensional array

--------------------------------------------------------------------*/

#define FIRST_DIM_SIZE(array) sizeof((array)) / sizeof((array[0]))

/************************Structures***********************************

Reservation

Contains :
- flight_nb[6] : The flight number ( 4 digits max )
- orig_air_code[5] : The origin airport code ( 3 letters )
- dest_air_code[5] : The destination airport code ( 3 letters )
- start_time[7] : Starting time [2 digits : 2 digits]
- end_time[7] : Arrival time [2 digits : 2 digits]

*********************************************************************/

typedef struct {
char flight_nb[6];
char orig_air_code[5];
char dest_air_code[5];
char start_time[7];
char end_time[7];
} reservation;

/*********************************************************************

NAME : wipestring( string )

USAGE : Wipe useless values from the string...

PARAMETERS : char const *string to wipe...

*********************************************************************/

static void
wipestring (char const *string)
{
/* We search a '\n' character */
char *p = strchr (string, '\n');

/* We found it, we replace it by '\0' */ if (p)
{
*p = '\0';
}

/* We don't find it, so we get everything pending in stdin */ else
{
int c;

while ((c = getchar ()) != '\n' && c != EOF) {
}
}
}

/*********************************************************************

NAME : getstring ( string, size )

USAGE : Take the user input and verify it...

PARAMETERS :
- The string to check and to fill if the user enter something - The
size of the string

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
getstring (char *string, size_t size) {
/* The error number */
int err = EXIT_SUCCESS;

/* Check if there's an input */
if (fgets (string, (int) size, stdin) == NULL) {
(void) printf ("Input Error\n");
err = EXIT_FAILURE;
}

else
{
/* Is the input too large ? */
if ( strchr(string, '\n') == NULL )
{
(void) printf("Input too large.\n");
wipestring(string);
err = EXIT_FAILURE;
}

/* If we got a '\n', does he enter something ? */ if ( err ==
EXIT_SUCCESS )
{

/* Wipe useless values */
wipestring (string);

if (*string == '\0')
{
(void) printf ("No input\n");
err = EXIT_FAILURE;
}

}
}

return err;
}

/*********************************************************************

NAME : get_answer( *string, input_size )

USAGE : Print an input area with a space determined by the size of
the value to take and take the value.

PARAMETERS :
- The string to store the input.
- The size of this input.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
get_answer ( char *string, size_t input_size ) {
/* Exit status */
int err = EXIT_SUCCESS;

/* Variable used for repetitions */
size_t i = 0;

/* If we can't write anything in the string, this is useless */ #ifdef
DEBUG
if ( input_size < 3 )
{
(void) fprintf(stderr, "Input size allocated too small !"); err =
EXIT_FAILURE;
} else
#endif /* DEBUG */

{

/* Information about the number of char authorized */ (void)
printf("(%d char max)", (int) input_size - 2);

(void) printf("[");

/* sizeof returns the real size of an array, but for a string
we got 2 reserved places ( "string\n\0" ) */

/* Design the input area */
for (i = 0; i < input_size - 2; i++ ) {
(void) printf("-");
}

(void) printf("]");

/* stdin got ( input_size - 2 ) + 1 char, to put the user
inside the input area we go (input_size - 1) chars back */

/* Put the user inside the input area */ for (i = 0; i <
input_size - 1; i++ ) {
(void) printf("\b");
}


}

/* If nothing is wrong, grab the user value */ if ( err ==
EXIT_SUCCESS )
{
err = getstring(string, input_size);
}

return err;

}

/*********************************************************************

NAME : checkcode ( *string, input_size )

USAGE : Check the airport code entered by the user.

PARAMETERS :
- The airport code
- Its size.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checkcode ( char *string, size_t input_size ) {
/* Exit status */
int err = EXIT_SUCCESS;

/* The code number */
int number = 0;

/* The airport codes */
char codes[][5] = { "JPU", "NYC", "TYO", "TXL", "LCY", "HKG" };

#ifdef DEBUG

/* We check if the pointer points to something */ if ( string == NULL
)
{
(void) fprintf(stderr, "Invalid string pointer"); err =
EXIT_FAILURE;
}

/* The input_size must be equal to 5 (XXX\n\0) */ else if ( input_size
!= 5 )
{
(void) fprintf(stderr, "Input under/oversized."); err =
EXIT_FAILURE;
} else

#endif /* DEBUG*/

/* We get the airport code */
if ( err == EXIT_SUCCESS )
err = get_answer(string, input_size);

/* We check if the code is correct */ if ( err == EXIT_SUCCESS )
{
/* We reset the exit status */
err = EXIT_FAILURE;

/* The code is compared to each code in the code database */ for
(number = 0; number < FIRST_DIM_SIZE(string) + 1 &&
err != EXIT_SUCCESS; number++)
{
if ( strcmp(string, codes[number]) == 0 )
err = EXIT_SUCCESS;
}

/* If the user entered a wrong code, say it to him */ if ( err ==
EXIT_FAILURE )
(void) printf("Wrong airport code");
}

return err;
}

/*********************************************************************

NAME : checktime ( *string, input_size )

USAGE : Check if the user entered a valid time.

PARAMETERS :
- Time entered by the user
- Input size

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checktime (char *string, size_t input_size) {
/* Exit status */
int err = EXIT_SUCCESS;

/* Time values : Hour and minutes */
unsigned short int time[2] = { 0, 0 };

/* Debug : We check if the pointer is valid */ #ifdef DEBUG
if ( string == NULL )
{
(void) fprintf(stderr, "Invalid string pointer.\n"); err =
EXIT_FAILURE;
}

/* Debug : We check if the input_size is correct
It must be 7 ( xx:xx\n\0 ) */
else if ( input_size != 7 )
{
(void) fprintf(stderr, "Input under/oversized. Must be 7.\n"); err
= EXIT_FAILURE;
}
#endif /* DEBUG */

/* We get the time */
err = get_answer(string, input_size);

/* We verify if the user put the separator */ if ( string[2] != ':' )
{
(void) puts("Wrong separator or not placed correctly"); err =
EXIT_FAILURE;
}

/* We check if the user doesn't enter a letter at the end */ else if (
isdigit(string[4]) == 0 )
{
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* We check if the user entered two numbers */ else if (
sscanf(string, "%02hu:%02hu", &time[0], &time[1]) != 2 ) {
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* Are the time values correct ? */
else if ( ( time[0] > 23 ) || ( time[1] > 59 ) ) {
(void) puts("Wrong time, the maximal value for the hour is 23");
err = EXIT_FAILURE;
}

return err;

}

/*********************************************************************

NAME : ask ( *client_fl )

USAGE : Take the principal informations about the flight and do
some basic check.

PARAMETER : The client reservation data structure.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
ask ( reservation *client_fl )
{
/* Error status */
int err = EXIT_SUCCESS;

assert( client_fl != NULL );

/* We check if the pointer point to something */ if ( client_fl ==
NULL )
{
(void) fprintf(stderr, "Data structure pointer client_fl is
invalid"); err = EXIT_FAILURE;
}

/* If everything is ok, we ask the first question */ else {
(void) puts("What's the starting airport code :");

err = checkcode(client_fl->orig_air_code,
sizeof(client_fl->orig_air_code));
}

/* Ok ? Next question */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's the destination airport code :");

err = checkcode(client_fl->dest_air_code,
sizeof(client_fl->dest_air_code));
}

/* The flight number */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's your flight number :");

err = get_answer(client_fl->flight_nb,
sizeof(client_fl->flight_nb));
}

/* Starting and arrival time */
if ( err == EXIT_SUCCESS )
{
(void) puts("The flight will start at : ( Valid times are 00:00 ->
23:59 )"); err = checktime(client_fl->start_time,
sizeof(client_fl->start_time));
}

if ( err == EXIT_SUCCESS )
{
(void) puts("The plane will arrive at : ( Valid times are 00:00 ->
23:59 )"); err = checktime(client_fl->end_time,
sizeof(client_fl->end_time));
}

/* If everything is ok, we print the user's flight information */ if (
err == EXIT_SUCCESS )
{
(void) printf("You start from | %s\n"
"You'll fly to | %s\n"
"Your flight number is | %s\n"
"The plane will lift off at | %s\n"
"The plane will arrive at | %s\n",
client_fl->orig_air_code,
client_fl->dest_air_code,
client_fl->flight_nb,
client_fl->start_time,
client_fl->end_time);
}

return err;

}

/*********************************************************************

NAME : aircodes ( void )

USAGE : Display program version and airport codes.

*********************************************************************/

static void
aircodes ( void )
{
(void) puts("Flight reservation v0.1"); (void)
puts("---------------------------------------------------------");
(void) puts("Airport codes :");
(void) printf("\nJPU - Paris La Defense\n"
"NYC - New York Multiple City Code\n" "TYO - Tokyo Narita\n"
"TXL - Berlin Tegel\n"
"LCY - London City\n"
"HKG - Hong Kong Intl\n");
(void)
printf("---------------------------------------------------------\n\n");
}

int main ( void )
{
/* Final exit status */
int err = EXIT_SUCCESS;

/* The data structure which contains client flight informations */
reservation client_fl = {{0}, {0}, {0}, {0}, {0}};

/* Display the airport codes */
aircodes();

/* Get the client flight informations */ (void) puts("Welcome.");

err = ask( &client_fl );

return err;
}

10 réponses

1 2 3 4 5
Avatar
Eddahbi Karim
Voici le code avec quelque petits changements et une fonction de test.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ggets.h"

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = EXIT_SUCCESS, NOMEM = EXIT_FAILURE};

int fggets(char **ln, FILE *f)
{
/* The current size and the size of the line read */
int cursize, readsize;

/* The buffer to store the input, the variable to test memory
allocations result, the read pointer position, the last char */
char *buffer, *temp, *readpoint, *crlocn;

*ln = (char *)'';

/* Can't allocate the memory, quit */
if (NULL == (buffer = malloc(INITSIZE)))
{
return NOMEM;
}

/* Initialize sizes variables */
cursize = readsize = INITSIZE;

/* For the moment, input read and stored are the same */
readpoint = buffer;

*buffer = '';

/* We check if we can get the current line in the input */
if (NULL == fgets(readpoint, readsize, f))
{
free(buffer);
return EOF;
}

/* We can't locate any 'n', the size allocated is too small */
while (NULL == (crlocn = strchr(readpoint, 'n')))
{

/* We read the next 128 char + ' */
readsize = DELTASIZE + 1;

/* The size of the line will be 128 chars bigger */
cursize = cursize + DELTASIZE;

if (NULL == (temp = realloc(buffer, (size_t)cursize)))
{
/* ran out of memory */

/* Give at last the part read from the input */
*ln = buffer;
return NOMEM;
}

/* Reallocate "buffer" memory */
buffer = temp;

/* Reposition the pointer to continue */
readpoint = buffer + (cursize - DELTASIZE - 1);


/* Can we get the next part of the line ? */
if (NULL == fgets(readpoint, readsize, f))
{
/* We can't ? place a '' at the end of the buffer */
crlocn = strchr(buffer, '');
break;
}
}

/* Strip the 'n' */
*crlocn = '';

/* Get the difference between
the real size and the size allocated */

readsize = crlocn - buffer;

/* Reallocate less memory. */
if (NULL == (temp = realloc(buffer, (size_t)readsize + 1)))
*ln = buffer; /* without reducing it */
else
*ln = temp;
return OK;
}



int main ( void )
{
char *foo = (char *)'';

printf("Something : ");
if ( EOF == fggets(&foo, stdin) )
{
(void) puts("Error");
}
(void) printf("%s", foo);

free(foo);
foo = NULL;

return 0;
}


Le code marche mais splint semble ne pas être d'accord sur la façon de
faire, mais je n'arrive pas à déterminer ce qu'il veut.

splint test2.c
Splint 3.0.1.6 --- 23 May 2003

test2.c: (in function fggets)
test2.c:58:16: Variable buffer used after being released
Memory is used after it has been released (either by passing as an only param
or assigning to an only global). (Use -usereleased to inhibit warning)
test2.c:53:35: Storage buffer released
test2.c:79:5: Variable crlocn used in inconsistent state
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
test2.c:53:35: Storage crlocn becomes inconsistent (released on one branch)
test2.c:87:32: Unallocated storage buffer passed as out parameter: buffer
test2.c:88:13: Variable buffer used after being released
test2.c:87:32: Storage buffer released

Finished checking --- 4 code warnings


Apparemment il aime pas les ré-allocations de buffer mais comment faire
pour que splint soit content ? :) (Hormis -usereleased :p)

Voila,
ThE_TemPLaR
Avatar
Bertrand Mollinier Toublet
Eddahbi Karim wrote:

Voici le code avec quelque petits changements et une fonction de test.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ggets.h"

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = EXIT_SUCCESS, NOMEM = EXIT_FAILURE};

int fggets(char **ln, FILE *f)
{
/* The current size and the size of the line read */
int cursize, readsize;

/* The buffer to store the input, the variable to test memory
allocations result, the read pointer position, the last char */
char *buffer, *temp, *readpoint, *crlocn;

*ln = (char *)'';
C'est quoi cette horreur ? Ca veut rien dire du tout. '' est

conventionnellement le character nul, celui qui termine les chaines de
caracteres. En C, il est de type int. Tu castes ca vers un pointeur de
char ? Ca n'a pas de sens !?! C'est pas l'IOCCC ici !
Les formes correctes et acceptables sont:
*ln = NULL;
*ln = 0;
C'est tout.
Juste par curiosite: explique-moi donc ce qui t'a pousse a faire cette
modif'.

<snip>
Le reste de la fonction est OK. C'est assez triste quand meme. J'ai
l'impression de lire du code que j'aurais modifie moi-meme. C'est la
meme chose et en meme temps, ce n'est plus la meme chose. Souviens toi
bien que le reformatage de code n'apporte pas grand chose et consome
enormement de temps... J'en suis vite revenu.


int main ( void )
{
char *foo = (char *)'';
Idem. Ca veut rien dire du tout tel que c'est ecrit.

char *foo = 0;
ou
char *foo = NULL;

printf("Something : ");
fflush(stdout);


if ( EOF == fggets(&foo, stdin) )
{
(void) puts("Error");
}
(void) printf("%s", foo);

free(foo);
foo = NULL;

return 0;
}


Le code marche mais splint semble ne pas être d'accord sur la façon de
faire, mais je n'arrive pas à déterminer ce qu'il veut.

Le code a l'air bon, oui. A part les initialisations esoteriques des

pointeurs de char.

splint test2.c
Splint 3.0.1.6 --- 23 May 2003

test2.c: (in function fggets)
test2.c:58:16: Variable buffer used after being released
Memory is used after it has been released (either by passing as an only param
or assigning to an only global). (Use -usereleased to inhibit warning)
test2.c:53:35: Storage buffer released
Au pif les numeros de ligne sont les suivants, non ?


53 if (NULL == (temp = realloc(buffer, (size_t)cursize)))
54 {
55 /* ran out of memory */
57 /* Give at last the part read from the input */
58 *ln = buffer;
59 return NOMEM;
60 }

Ce que splint ne voit pas, apparement, c'est que a l'interieur du if, le
realloc a echoue, si bien que buffer n'est pas "released" libere. Moi je
classerais ca comme l'un des innombrables bugs de splint. Essaie d'en
parler sur la mailing list. Peut-etre que les gars auront des
conseils/workaround a te donner.

test2.c:79:5: Variable crlocn used in inconsistent state
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
test2.c:53:35: Storage crlocn becomes inconsistent (released on one branch)


Ah oui. Bin oui. C'est encore un "bug" de splint. Ligne 53, en effet,
crlocn devient inconsistent. Heureusement, avant d'arriver a la ligne
79, ou bien le realloc de la ligne 53 echoue, et on quitte la fonction.
Ou bien fgets retourne NULL ligne 70, et crlocn recupere une valeur
valide ligne 73 avant de quitter le while ligne 74 et d'arriver a la
ligne 79. Ou bien le while boucle, et crlocn recupere une valeur valide
ligne 44, auquel cas, ou bien on repart dans la boucle, ou bien on la
quitte avec crlocn initialise a une valeur valide.

test2.c:87:32: Unallocated storage buffer passed as out parameter: buffer
test2.c:88:13: Variable buffer used after being released
test2.c:87:32: Storage buffer released


Les deux warnings ci-dessus sont lies aux memes causes et effet que le
premier warning: splint ne voit pas que si realloc retourne NULL, son
argument n'a pas ete libere...


Finished checking --- 4 code warnings


Apparemment il aime pas les ré-allocations de buffer mais comment faire
pour que splint soit content ? :) (Hormis -usereleased :p)



C'est pas de l'open-source, Splint ? Parce que si oui, le meilleur moyen
de le rendre content, c'est de le reparer :-)

Voila,
ThE_TemPLaR


Tu veux faire un truc bien ? Il y a une facon standard de separer sa
signature du corps de son message, c'est comme ci-dessous la sequence
<tiret><tiret><espace><retour a la ligne>. Un logiciel de messagerie
intelligent (chez moi: Mozilla Thunderbird) est capable de couper ta
signature quand je te reponds, de changer de signature on the fly, etc.
grace a cette petite feature...

--
Bertrand Mollinier Toublet
"In regard to Ducatis vs. women, it has been said: 'One is a sexy thing
that you've just got to ride, even if it breaks down a lot, costs a lot
of money, and will probably try to kill you'. However, nowadays I can't
seem to remember which one is which." -- Peer Landa

Avatar
Eddahbi Karim

Eddahbi Karim wrote:

[snip]


*ln = (char *)'';
C'est quoi cette horreur ? Ca veut rien dire du tout. '' est

conventionnellement le character nul, celui qui termine les chaines de
caracteres. En C, il est de type int. Tu castes ca vers un pointeur de
char ? Ca n'a pas de sens !?! C'est pas l'IOCCC ici !
Les formes correctes et acceptables sont:
*ln = NULL;
*ln = 0;
C'est tout.
Juste par curiosite: explique-moi donc ce qui t'a pousse a faire cette
modif'.


Mooh pas tapé, c'est splint qui crie quand je mets 0, quand je mets ''
et quand je mets NULL.


<snip>
Le reste de la fonction est OK. C'est assez triste quand meme. J'ai
l'impression de lire du code que j'aurais modifie moi-meme. C'est la
meme chose et en meme temps, ce n'est plus la meme chose. Souviens toi
bien que le reformatage de code n'apporte pas grand chose et consome
enormement de temps... J'en suis vite revenu.


Ben je voulais juste bien comprendre la fonction, étant donné que c'est
pas la mienne (non j'ai pas reformaté mon stdio :)), et que y'avait des
points que j'avais du mal à cerner.
Ça m'a permis de voir comment étudier un code source :).

[snip]
int main ( void )
{
char *foo = (char *)'';
Idem. Ca veut rien dire du tout tel que c'est ecrit.

char *foo = 0;
ou
char *foo = NULL;


C'est ce que j'avais fait, mais splint... enfin bon, je vais voir si il y
a pas d'autres moyens de vérifier un code source :).


printf("Something : ");
fflush(stdout);




Effectivement, ceci dit c'est une fonction à la va vite pour tester le
EOF, je voulais voir dans quelle circonstance ça aurait pu marcher (genre
si je rentre rien, EOF ou pas ?).

Quand j'ai ce genre de questions je fais des petits test :)

[snip]

Le code a l'air bon, oui. A part les initialisations esoteriques des
pointeurs de char.


Mais... mais... mais j'aime bien la crème chantilly... pas tapé !

[snip]

Au pif les numeros de ligne sont les suivants, non ?

53 if (NULL == (temp = realloc(buffer, (size_t)cursize)))
54 {
55 /* ran out of memory */
57 /* Give at last the part read from the input */
58 *ln = buffer;
59 return NOMEM;
60 }

Ce que splint ne voit pas, apparement, c'est que a l'interieur du if, le
realloc a echoue, si bien que buffer n'est pas "released" libere. Moi je
classerais ca comme l'un des innombrables bugs de splint. Essaie d'en
parler sur la mailing list. Peut-etre que les gars auront des
conseils/workaround a te donner.


Effectivement, je devais justement m'abonner à une autre mailing list...
Pauvre boite à mail...


test2.c:79:5: Variable crlocn used in inconsistent state
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
test2.c:53:35: Storage crlocn becomes inconsistent (released on one branch)


Ah oui. Bin oui. C'est encore un "bug" de splint. Ligne 53, en effet,
crlocn devient inconsistent. Heureusement, avant d'arriver a la ligne
79, ou bien le realloc de la ligne 53 echoue, et on quitte la fonction.
Ou bien fgets retourne NULL ligne 70, et crlocn recupere une valeur
valide ligne 73 avant de quitter le while ligne 74 et d'arriver a la
ligne 79. Ou bien le while boucle, et crlocn recupere une valeur valide
ligne 44, auquel cas, ou bien on repart dans la boucle, ou bien on la
quitte avec crlocn initialise a une valeur valide.


-usedef alors ? :)


test2.c:87:32: Unallocated storage buffer passed as out parameter: buffer
test2.c:88:13: Variable buffer used after being released
test2.c:87:32: Storage buffer released


Les deux warnings ci-dessus sont lies aux memes causes et effet que le
premier warning: splint ne voit pas que si realloc retourne NULL, son
argument n'a pas ete libere...


Ok, bon ben mailing list :).



C'est pas de l'open-source, Splint ? Parce que si oui, le meilleur moyen
de le rendre content, c'est de le reparer :-)


Déjà que je me débrouille à peine avec mon code, alors splint... :D


Voila,
ThE_TemPLaR



Tu veux faire un truc bien ?


C'est dit d'une façon :)

Il y a une facon standard de separer sa
signature du corps de son message, c'est comme ci-dessous la sequence
<tiret><tiret><espace><retour a la ligne>. Un logiciel de messagerie
intelligent (chez moi: Mozilla Thunderbird) est capable de couper ta
signature quand je te reponds, de changer de signature on the fly, etc.
grace a cette petite feature...


Voilà c'est changé pour la prochaine réponse :).

--
ThE_TemPLaR (signature généré à la main car plus mieux) :)


Avatar
Bertrand Mollinier Toublet
Eddahbi Karim wrote:

Mooh pas tapé, c'est splint qui crie quand je mets 0, quand je mets ''
et quand je mets NULL.

Et il dit quoi splint ?

Honnetement, je l'avais... et je l'ai vire. Marre des millions de
warnings sans justification tres valide.

<snip>
Le reste de la fonction est OK. C'est assez triste quand meme. J'ai
l'impression de lire du code que j'aurais modifie moi-meme. C'est la
meme chose et en meme temps, ce n'est plus la meme chose. Souviens toi
bien que le reformatage de code n'apporte pas grand chose et consome
enormement de temps... J'en suis vite revenu.


Ben je voulais juste bien comprendre la fonction, étant donné que c'est
pas la mienne (non j'ai pas reformaté mon stdio :)), et que y'avait des
points que j'avais du mal à cerner.
Ça m'a permis de voir comment étudier un code source :).

Oui oui. Je sais bien. J'espere que ca te passera quand meme.


[snip]

int main ( void )
{
char *foo = (char *)'';


Idem. Ca veut rien dire du tout tel que c'est ecrit.
char *foo = 0;
ou
char *foo = NULL;



C'est ce que j'avais fait, mais splint... enfin bon, je vais voir si il y
a pas d'autres moyens de vérifier un code source :).

Splint est bien, mais il y a un peu trop de faux positifs !

Ton compilateur avec un niveau de warning pousse a fond plus un
utilitaire de suivi de consommation de memoire (memtrack...) plus poster
sur f.c.l.c est mieux, quoiqu'un peu lourd :-D

test2.c:79:5: Variable crlocn used in inconsistent state
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
test2.c:53:35: Storage crlocn becomes inconsistent (released on one branch)


Ah oui. Bin oui. C'est encore un "bug" de splint. Ligne 53, en effet,
crlocn devient inconsistent. Heureusement, avant d'arriver a la ligne
79, ou bien le realloc de la ligne 53 echoue, et on quitte la fonction.
Ou bien fgets retourne NULL ligne 70, et crlocn recupere une valeur
valide ligne 73 avant de quitter le while ligne 74 et d'arriver a la
ligne 79. Ou bien le while boucle, et crlocn recupere une valeur valide
ligne 44, auquel cas, ou bien on repart dans la boucle, ou bien on la
quitte avec crlocn initialise a une valeur valide.


-usedef alors ? :)

Euh... a voir sur la mailing-list. Souviens toi aussi qu'un gros

principe de splint est le principe des annotations. En annotant ton code
(avec la syntaxe de splint), tu explicites a la fois pour splint et pour
les lecteurs de ton code les subtilites du genre variable in, out et
autres bazars. Peut-etre qu'une annotation ou deux vont pouvoir resoudre
tes problemes.

C'est pas de l'open-source, Splint ? Parce que si oui, le meilleur moyen
de le rendre content, c'est de le reparer :-)


Déjà que je me débrouille à peine avec mon code, alors splint... :D

Oui. Je deconnais.


Voilà c'est changé pour la prochaine réponse :).

Bien joue. Merci. Normalement, il n'y a meme pas besoin de le faire a la

main. Je ne connais pas ton client (pan ?), mais il doit y avoir moyen
de le forcer a te faire une signature correcte.

--
Bertrand Mollinier Toublet
[A] Top-posting.
[Q] What's the most annoying thing on Usenet ?



Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Eddahbi Karim
wrote:

*ln = (char *)'';
<...>



Les formes correctes et acceptables sont:
*ln = NULL;
*ln = 0;



A condition que ce soit la définition de ln. Sinon

char *ln = NULL;
char *ln = 0;

sont corrects.

Si on veut mettre un 0, c'est:

*ln = 0;
*ln = '';

Mooh pas tapé, c'est splint qui crie quand je mets 0, quand je mets ''
et quand je mets NULL.


Certes, mais c'est sans doute debrayable (Tous les warnings de splint ne sont
pas intéressants...). Sinon, le cast est carrément faux (bien que 0 soit un
cas particulier). M'étonnerait que Lint laisse passer ça... Ou alors ce n'est
pas le code original.

int main ( void )
{
char *foo = (char *)'';
Idem. Ca veut rien dire du tout tel que c'est ecrit.

char *foo = 0;
ou
char *foo = NULL;


C'est ce que j'avais fait, mais splint... enfin bon, je vais voir si il
y a pas d'autres moyens de vérifier un code source :).


Est-tu sûr qu'il est configuré pour vérifier du C et non un autre langage? Je
serais curieux de lire le message de splint pour

int main ( void )
{
char *foo = NULL;

parce qu'avec PCLint, c'est OK.

Il y a une facon standard de separer sa
signature du corps de son message, c'est comme ci-dessous la sequence
<tiret><tiret><espace><retour a la ligne>.


Voilà c'est changé pour la prochaine réponse :).


Apparament, ça marche, car je ne vois plus ta signature (XNews)

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/



Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Bertrand Mollinier Toublet
wrote:

<--- >

Bien joue. Merci. Normalement, il n'y a meme pas besoin de le faire a la
main. Je ne connais pas ton client (pan ?), mais il doit y avoir moyen
de le forcer a te faire une signature correcte.


Automatique avec XNews...

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Bertrand Mollinier Toublet
Emmanuel Delahaye wrote:

In 'fr.comp.lang.c', Eddahbi Karim
wrote:


*ln = (char *)'';




<...>

Les formes correctes et acceptables sont:
*ln = NULL;
*ln = 0;




A condition que ce soit la définition de ln. Sinon

char *ln = NULL;
char *ln = 0;

sont corrects.

Si on veut mettre un 0, c'est:

*ln = 0;
*ln = '';

Tu as rate le contexte (mais je t'accorde que c'est pas clair). Il

s'agit de:

char **ln

Dans ce contexte, ma remarque est valide. Pour que ln pointe vers un
pointeur nul, les formes correctes et acceptables sont:

*ln = NULL;
ou
*ln = 0;

--
Bertrand Mollinier Toublet
- Le top-posting.
- Quelle est la pratique la plus chiante sur Usenet ?




Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Bertrand Mollinier Toublet
wrote:

Tu as rate le contexte (mais je t'accorde que c'est pas clair). Il
s'agit de:

char **ln

Dans ce contexte, ma remarque est valide. Pour que ln pointe vers un
pointeur nul, les formes correctes et acceptables sont:

*ln = NULL;
ou
*ln = 0;


Ok, à condition que 'ln' soit correctement initialisé.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Eddahbi Karim

[snip]

Si je fais ça, splint me dit rien par contre si je fais ça dans le
programme de test :

test2.c:105:25: Null storage foo passed as non-null param:
printf (..., foo, ...)
A possibly null pointer is passed as a parameter corresponding to a formal
parameter with no /*@null@*/ annotation. If NULL may be used for this
parameter, add a /*@null@*/ annotation to the function parameter declaration.
(Use -nullpass to inhibit warning)
test2.c:98:17: Storage foo becomes null

Apparament, ça marche, car je ne vois plus ta signature (XNews)


J'avais fait un test sur fr.test :)

--
ThE_TemPLaR

Avatar
Eddahbi Karim

[snip]

C'est fait, c'est fait.
--
ThE_TemPLaR
1 2 3 4 5