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

warning: function returns address of local variable

65 réponses
Avatar
pere.noel
à la compile d'un ensemble de fonctions + main, j'ai le message de
warning :
function returns address of local variable
pour la fonction "target_path_normalize"

le but de cette fonction :
si j'ai en entrée :

target_path_checked =
////Users////yvon/./////////////////////work/C/../.headers
toto/CFArray.h

elle retourne ce path normalisé :
target_path_normalized = /Users/yvon/work/.headers toto/CFArray.h

cette fonction "marche" mais je me demande quel risque je prends en
laissant trainer ce warning

le contexte : avant l'utilisation de cette fonction, j'en utilise une
autre "target_path_check" qui retourne NULL si le path n'est pas absolu
et accessoirement supprime le "/" en fin de chaîne s'il existe.

--- target_path_normalize ---------------------------------------------
char* target_path_normalize(const char* target_path)
{
int trente_deux = 32; /* maximum de répertoires traversés */
int mille_vingt_quatre = 1024; /* taille maximum d'un path */
char p[mille_vingt_quatre]="";
char *q;
char *token;
const char needle[] = "/";
const char *dot = ".";
const char *dotdot = "..";
int j;
q = strdup(target_path);
j = 0;
char *pieces[trente_deux];
// initialisation des éléments du tableau à NULL
while(j < trente_deux) {
pieces[j] = NULL;
j++;
}

// démarrage du découpage de q (target_path)
token = strtok(q, needle);
j = 0;

// découpage de q (target_path)
while(token != NULL) {
// si ".." on décrémente j equivalent à cd ..
// si "." on ne fait rien
// si différent de ".." et de "." on enregistre token dans
pieces[j] et on incrémente j
if(strcmp(token, dotdot) == 0) {
j--;
} else if(strcmp(token, dot) != 0) {
pieces[j]=token;
j++;
}
token = strtok(NULL, needle);
}
j = 0;

// concaténation de "/" (needle) et de pieces[j] jusqu'à épuisement
(quand pieces[j] == NULL)
while(pieces[j] != NULL) {
strcat(p, needle);
strcat(p, pieces[j]);
j++;
}
return p;
}
-----------------------------------------------------------------------
donc c'est le "return p" qui pose pb à la compil mais pas à
l'utilisation.
--
une bévue

10 réponses

Avatar
Harpo
Une bévue wrote:

ce que je trouve "génial" là-dedans c'est les lignes :
*q = 0;
q--;


C'est verbeux.

*(q--) = 0;
est plus lisible.

--
http://patrick.davalan.free.fr/

Avatar
Hamiral
Une bévue wrote:
int trente_deux = 32; /* maximum de répertoires traversés */
int mille_vingt_quatre = 1024; /* taille maximum d'un path */
char p[mille_vingt_quatre]="";


Euh, peut-être que quelqu'un l'a déjà dit, mais moi ça ça me fait bondir ...
Avoir une variable appelée trente_deux qu'on initialise à 32, ça rime à
quoi ?
Et si après, tu veux augmenter le nombre maximum de répertoires traversés,
tu renommes la variable aussi, et tu modifies tout ton code ???
Le mieux, ce serait de passer ces pseudo-constantes en tant que paramètres à
ta fonction, un truc du genre :

/**
* @param maxrep Maximum de répertoires traversés. Si cette valeur est
inférieure ou égale à 0, 32 est utilisé comme valeur par défaut.
* @param maxpathlength Taille maximum d'un path. Si cette valeur est
inférieure ou égale à 0, 1024 est utilisé comme valeur par défaut.
*/
char* target_path_normalize(const char* target_path, int maxrep, int
maxpathlength)

Et après, tu initialises p avec le malloc qui va bien, et ta fonction est
tout à fait modulaire et utilisable dans tous les cas que tu peux imaginer.

--
Hamiral

Avatar
Eric Levenez
Le 7/09/06 21:30, dans <4500738d$0$31640$, « Harpo »
a écrit :

Une bévue wrote:

ce que je trouve "génial" là-dedans c'est les lignes :
*q = 0;
q--;


C'est verbeux.

*(q--) = 0;
est plus lisible.


Les parenthèses ne servent ici qu'à surcharger inutilement la lecture, un
peu comme les :

return(0);

que l'on voit trop souvent :-)

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
gl


Les parenthèses ne servent ici qu'à surcharger inutilement la lecture,


Egalement à lever les ambiguïtés de lecture. Nombreux sont les
développeurs pour qui la signification de *q-- (ou d'autres expressions
du même style) n'est pas immédiate. Autant être rapidement
compréhensible par le maximum de relecteurs potentiels.

Avatar
gl
Stéphane Goujet wrote:

sizeof(char) vaut toujours 1 (par définition).


oui, mais c'est plus zoli )))


Un écriture plus classique et qui permet en outre une maintenance accrue
si le type de str3 est amené à changer (il ne sera pas nécessaire alors
de modifier le code de l'allocation) est de remplacer :

str3 = (char *)calloc(PATH_SIZE_MAX, sizeof(char));

par

str3 = calloc(PATH_SIZE_MAX, sizeof *str3);


Avatar
pere.noel
Eric Levenez wrote:

en C tu veux dire ?


Le type 160 bits n'existe pas en C.

c'est pas très chouette côté occupation mémoire quand la machine a des
mots de 32 bits. ça me surprend il doit y avoir un quiproquo.


Oui. Mais sur un DSP 32 bits, on utilise rarement des char : ces CPU sont
fait pour faire de gros calculs rapidement, pas pour traiter du texte car un
simple "hello word" prend 4 fois plus de place en mémoire que sur un Cpu 32
bits traditionnel


ben oui, c'est pas fait pour.


On ne caste pas en C le retour de calloc ou de malloc.


ah bon, j'ai pris ça sur un tuto somewhere...


On ne fait jamais sizeof(char) car cela vaut 1 par définition.

Quand tu veux mettre dans la variable n le nombre de 1000 carottes, tu ne
fais pas...

n = 1000 * 1;

...pour indiquer que c'est 1000 fois 1 carotte.



pas en ADA hein ;-)

Si tu veux marquer ton code pour y revenir plus tard (traitement UTF-8 comme
tu le disais), alors mets des commentaires du type :

// TODO : passer en UTF-8

Après tu rechercheras les TODO.


bonne idée !
--
une bévue


Avatar
pere.noel
gl wrote:


str3 = calloc(PATH_SIZE_MAX, sizeof *str3);


je vois, pas con !
--
une bévue

Avatar
pere.noel
Hamiral wrote:

Euh, peut-être que quelqu'un l'a déjà dit, mais moi ça ça me fait bondir ...
Avoir une variable appelée trente_deux qu'on initialise à 32, ça rime à
quoi ?


oui, oui, moi aussi ça m'a fait réagir ))

Et si après, tu veux augmenter le nombre maximum de répertoires traversés,
tu renommes la variable aussi, et tu modifies tout ton code ???
Le mieux, ce serait de passer ces pseudo-constantes en tant que paramètres à
ta fonction, un truc du genre :

/**
* @param maxrep Maximum de répertoires traversés. Si cette valeur est
-----^---- le @ là c'est pour générer une doc, je suppose ?


inférieure ou égale à 0, 32 est utilisé comme valeur par défaut.
* @param maxpathlength Taille maximum d'un path. Si cette valeur est
inférieure ou égale à 0, 1024 est utilisé comme valeur par défaut.
*/
char* target_path_normalize(const char* target_path, int maxrep, int
maxpathlength)

Et après, tu initialises p avec le malloc qui va bien, et ta fonction est
tout à fait modulaire et utilisable dans tous les cas que tu peux imaginer.


mon code a beaucoup changé depuis cette "version brouillon", merci en
tout k.
--
une bévue

Avatar
Hamiral
Une bévue wrote:

Hamiral wrote:

Euh, peut-être que quelqu'un l'a déjà dit, mais moi ça ça me fait bondir
... Avoir une variable appelée trente_deux qu'on initialise à 32, ça rime
à quoi ?


oui, oui, moi aussi ça m'a fait réagir ))


Ok, alors je m'inquiétais pour rien :)

/**
* @param maxrep Maximum de répertoires traversés. Si cette valeur est
-----^---- le @ là c'est pour générer une doc, je suppose ?



Oui, j'utilise la syntaxe doxygen pour mes commentaires.


mon code a beaucoup changé depuis cette "version brouillon", merci en
tout k.


Y'a pas de quoi !

--
Hamiral


Avatar
Harpo
Eric Levenez wrote:

*(q--) = 0;
est plus lisible.


Les parenthèses ne servent ici qu'à surcharger inutilement la lecture,


Je ne me rappelle jamais de la précédence des opérateurs.

un peu comme les :

return(0);

que l'on voit trop souvent :-)


Ca donne un style macro.

--
http://patrick.davalan.free.fr/