Je dirais que oui (en plus, pas de warning) mais quand même j'ai un doute : bien
que les chaînes littérales soient en mémoire statique, le compilateur va-t-il
retourner la même adresse à chaque appel ? Bon en fait quand on dit que les
chaînes sont en mémoire statique, je trouve que c'est un peu vague. La Norme,
elle, dit :
A character string literal has static storage duration and type
"array of char ,"
mais dans un programme on écrit
int toto=42, titi;
titi=toto + strlen("zozo");
le compilateur place-t-il en mémoire statique la chaîne "zozo" parce que je vois
pas l'intérêt de le faire ? Par contre si on écrit
char *s="zozo";
je vois l'intérêt puisque l'adresse est utilisée par une variable
D'ailleurs, dans le premier exemple, la variable ok a-t-elle toujours la même
valeur ? Je crois que oui mais j'ai un petit doute.
La question est de savoir si "OK" existe en mémoire ou pas. J'avais crû comprendre qu'il n'y avait pas de garantie que l'objet n'existe pas :
Le code qui nous occupe est le suivant:
char *h(void) { char ok[]="OK"; return ok; }
Si on outrepasse les warnings et qu'on compile quand même cet étrange code, "OK" peut effectivement /exister/ pendant quelques nanosecondes en mémoire locale
Je crois que la discussion devient byzantine et qu'on va bientôt aborder la question du sexe des chaînes. Bon, moi j'avais compris que les chaînes littérales ("truc") étaient systématiquement placées en mémoire statique même si l'adresse n'était pas utilisée ou nécessaire (par exemple sizeof "truc"; ou char ok[]="OK";) et même d'après la Norme c'est en phase 7. Après, à quoi servent ces tableaux en mémoire statique lorsque l'adresse de la chaîne littérale n'est pas utile ? ça en fait je n'en sais rien. Comme tu l'as rappelé, char ok[]="OK"; revient à initialiser le tableau ok avec 3 caractères 'O', 'K' et 0, c'est vrai donc qu'on s'en fout de la chaîne "OK" en mémoire statique. Par contre, si on a char *ok="OK"; là on ne s'en fout pas puisque le tableau est converti en pointeur, d'ailleurs je suppose qu'on aurait pu écrire de façon équivalente : char *p=&"OK"[0];
Pierre Maurette a écrit :
candide, le 14/07/2009 a écrit :
Pierre Maurette a écrit :
candide, le 13/07/2009 a écrit :
[...]
Il n'y
a pas d'objet à copier.
La question est de savoir si "OK" existe en mémoire ou pas. J'avais crû
comprendre qu'il n'y avait pas de garantie que l'objet n'existe pas :
Le code qui nous occupe est le suivant:
char *h(void)
{
char ok[]="OK";
return ok;
}
Si on outrepasse les warnings et qu'on compile quand même cet étrange
code, "OK" peut effectivement /exister/ pendant quelques nanosecondes en
mémoire locale
Je crois que la discussion devient byzantine et qu'on va bientôt aborder la
question du sexe des chaînes. Bon, moi j'avais compris que les chaînes
littérales ("truc") étaient systématiquement
placées en mémoire statique même si l'adresse n'était pas utilisée ou nécessaire
(par exemple sizeof "truc"; ou char ok[]="OK";) et même d'après la Norme c'est
en phase 7. Après, à quoi servent ces tableaux en mémoire statique lorsque
l'adresse de la chaîne littérale n'est pas utile ? ça en fait je n'en sais rien.
Comme tu l'as rappelé, char ok[]="OK"; revient à initialiser le tableau ok
avec 3 caractères 'O', 'K' et 0, c'est vrai donc qu'on s'en fout de la chaîne
"OK" en mémoire statique. Par contre, si on a char *ok="OK"; là on ne s'en fout
pas puisque le tableau est converti en pointeur, d'ailleurs je suppose qu'on
aurait pu écrire de façon équivalente : char *p=&"OK"[0];
La question est de savoir si "OK" existe en mémoire ou pas. J'avais crû comprendre qu'il n'y avait pas de garantie que l'objet n'existe pas :
Le code qui nous occupe est le suivant:
char *h(void) { char ok[]="OK"; return ok; }
Si on outrepasse les warnings et qu'on compile quand même cet étrange code, "OK" peut effectivement /exister/ pendant quelques nanosecondes en mémoire locale
Je crois que la discussion devient byzantine et qu'on va bientôt aborder la question du sexe des chaînes. Bon, moi j'avais compris que les chaînes littérales ("truc") étaient systématiquement placées en mémoire statique même si l'adresse n'était pas utilisée ou nécessaire (par exemple sizeof "truc"; ou char ok[]="OK";) et même d'après la Norme c'est en phase 7. Après, à quoi servent ces tableaux en mémoire statique lorsque l'adresse de la chaîne littérale n'est pas utile ? ça en fait je n'en sais rien. Comme tu l'as rappelé, char ok[]="OK"; revient à initialiser le tableau ok avec 3 caractères 'O', 'K' et 0, c'est vrai donc qu'on s'en fout de la chaîne "OK" en mémoire statique. Par contre, si on a char *ok="OK"; là on ne s'en fout pas puisque le tableau est converti en pointeur, d'ailleurs je suppose qu'on aurait pu écrire de façon équivalente : char *p=&"OK"[0];
Eric Levenez
Le 14/07/09 00:00, dans <4a5bae81$0$421$, « candide » a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme dit : [snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 14/07/09 00:00, dans <4a5bae81$0$421$426a74cc@news.free.fr>, « candide »
<candide@free.invalid> a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque
l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme
dit :
[snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose
et une opération magique va changer la valeur de la variable locale p au
moment du free ?
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 14/07/09 00:00, dans <4a5bae81$0$421$, « candide » a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme dit : [snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Richard Delorme
Le 14/07/2009 10:43, Eric Levenez a écrit :
Le 14/07/09 00:00, dans<4a5bae81$0$421$, « candide » a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme dit : [snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois, mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
-- Richard
Le 14/07/2009 10:43, Eric Levenez a écrit :
Le 14/07/09 00:00, dans<4a5bae81$0$421$426a74cc@news.free.fr>, « candide »
<candide@free.invalid> a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque
l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme
dit :
[snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose
et une opération magique va changer la valeur de la variable locale p au
moment du free ?
D'accord, printf affichera la même chose les deux fois, mais en
pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas
déférencer (sauf comme borne d'un tableau).
Le 14/07/09 00:00, dans<4a5bae81$0$421$, « candide » a écrit :
Sauf que je ne vois pas comment on peut réutiliser le retour de f puisque l'objet renvoyé n'existe plus ou n'est plus censé exister d'ailleurs la Norme dit : [snip]
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois, mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
Donc d'après toi le code précédent ne va pas afficher 2 fois la même
chose
et une opération magique va changer la valeur de la variable locale p au
moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du
pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the
object it points to reaches the end of its lifetime.
mais en
pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas
déférencer (sauf comme borne d'un tableau).
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
-- Richard
-ed-
On 13 juil, 16:53, Pierre Maurette wrote:
A peu près autant que la rose de Malherbe, l'espace d'un matin. Je vous emmerde...
grossièreté inutile ...
On 13 juil, 16:53, Pierre Maurette <maurettepie...@wanadoo.fr> wrote:
A peu près autant que la rose de Malherbe, l'espace d'un matin. Je vous
emmerde...
Je me réjouis que Pierre Maurette et Emmanuel Delahaye soient capables de tenir une conversation cordiale avec moi ;)
Vous vous trompez. Là aussi.
... le tout étant de savoir combien de temps ça va durer ... ;)
A peu près autant que la rose de Malherbe, l'espace d'un matin. Je vous emmerde...
Si candide t'insupporte, utile un kill-file...
c'est vrai qu'il a des cotes jeune chiot rebelle passablement enervants, mais qunad meme !
-ed-
On 13 juil, 17:48, Pierre Maurette wrote:
> OK. Dans le même genre il y a quelque chose qui peut troubler le dé butant, > c'est l'absence de warning ici :
> int *f(void) > { > int okB; > int *p=&ok; > return p; > }
Il n'y a pas de vrai problème dans ce code.
Bah, on retourne l'adresse d'un objet qui n'existe plus ... A part ça tout va bien ...
La fonction retourne [une
copie de] la valeur du int* p. p a été initialisé par &ok, le programmeur exprime clairement sa volonté de faire ainsi. &ok est une *valeur numérique immédiate*, résolue éventuellement après la compilation, au niveau du lieur ou du loader, mais peu importe.
qui ne génère pas de warning. On exprime encore clairement sa volont é de retourner une copie de valeur.
... de coder une ânerie ... Tu devrais relire ton livre, je suis sûr que c'est expliqué ...
C'est peut-être un peu comme un
if(a=b){} qui va warner, alors que if((a=b) != 0){} voire if((a=b )){} vont faire taire le warning: je ne double pas les parenthèses par plaisir...
pfff... strictement aucun rapport...
Tu nous avais habitué à de meilleurs raisonnements... l'age, sans doute ...
On 13 juil, 17:48, Pierre Maurette <maurettepie...@wanadoo.fr> wrote:
> OK. Dans le même genre il y a quelque chose qui peut troubler le dé butant,
> c'est l'absence de warning ici :
> int *f(void)
> {
> int ok=42;
> int *p=&ok;
> return p;
> }
Il n'y a pas de vrai problème dans ce code.
Bah, on retourne l'adresse d'un objet qui n'existe plus ... A part ça
tout va bien ...
La fonction retourne [une
copie de] la valeur du int* p. p a été initialisé par &ok, le
programmeur exprime clairement sa volonté de faire ainsi. &ok est une
*valeur numérique immédiate*, résolue éventuellement après la
compilation, au niveau du lieur ou du loader, mais peu importe.
> OK. Dans le même genre il y a quelque chose qui peut troubler le dé butant, > c'est l'absence de warning ici :
> int *f(void) > { > int okB; > int *p=&ok; > return p; > }
Il n'y a pas de vrai problème dans ce code.
Bah, on retourne l'adresse d'un objet qui n'existe plus ... A part ça tout va bien ...
La fonction retourne [une
copie de] la valeur du int* p. p a été initialisé par &ok, le programmeur exprime clairement sa volonté de faire ainsi. &ok est une *valeur numérique immédiate*, résolue éventuellement après la compilation, au niveau du lieur ou du loader, mais peu importe.
qui ne génère pas de warning. On exprime encore clairement sa volont é de retourner une copie de valeur.
... de coder une ânerie ... Tu devrais relire ton livre, je suis sûr que c'est expliqué ...
C'est peut-être un peu comme un
if(a=b){} qui va warner, alors que if((a=b) != 0){} voire if((a=b )){} vont faire taire le warning: je ne double pas les parenthèses par plaisir...
pfff... strictement aucun rapport...
Tu nous avais habitué à de meilleurs raisonnements... l'age, sans doute ...
-ed-
On 14 juil, 00:40, Pierre Maurette wrote:
candide, le 14/07/2009 a écrit :
> Pierre Maurette a écrit :
>>> OK. Dans le même genre il y a quelque chose qui peut troubler le >>> débutant, c'est l'absence de warning ici :
>>> int *f(void) >>> { >>> int okB; >>> int *p=&ok; >>> return p; >>> }
>> Il n'y a pas de vrai problème dans ce code.
> Sauf que je ne vois pas comment on peut réutiliser le retour de f pui sque > l'objet renvoyé n'existe plus ou n'est plus censé exister
On se fout de l'objet. On dispose de la valeur d'un int*. On peut faire: printf("%pn", f()); sans danger...
Oui, afficher la valeur est techniquement possible. Mais parfaitement inutile. De plus, un pingouin de passage pourrait être tenté de déréférencer le pointeur et là, c'est le drame...
printf("%dn", *f());
On 14 juil, 00:40, Pierre Maurette <maurettepie...@wanadoo.fr> wrote:
candide, le 14/07/2009 a écrit :
> Pierre Maurette a écrit :
>>> OK. Dans le même genre il y a quelque chose qui peut troubler le
>>> débutant, c'est l'absence de warning ici :
>>> int *f(void)
>>> {
>>> int ok=42;
>>> int *p=&ok;
>>> return p;
>>> }
>> Il n'y a pas de vrai problème dans ce code.
> Sauf que je ne vois pas comment on peut réutiliser le retour de f pui sque
> l'objet renvoyé n'existe plus ou n'est plus censé exister
On se fout de l'objet. On dispose de la valeur d'un int*. On peut
faire:
printf("%pn", f());
sans danger...
Oui, afficher la valeur est techniquement possible. Mais parfaitement
inutile. De plus, un pingouin de passage pourrait être tenté de
déréférencer le pointeur et là, c'est le drame...
>>> OK. Dans le même genre il y a quelque chose qui peut troubler le >>> débutant, c'est l'absence de warning ici :
>>> int *f(void) >>> { >>> int okB; >>> int *p=&ok; >>> return p; >>> }
>> Il n'y a pas de vrai problème dans ce code.
> Sauf que je ne vois pas comment on peut réutiliser le retour de f pui sque > l'objet renvoyé n'existe plus ou n'est plus censé exister
On se fout de l'objet. On dispose de la valeur d'un int*. On peut faire: printf("%pn", f()); sans danger...
Oui, afficher la valeur est techniquement possible. Mais parfaitement inutile. De plus, un pingouin de passage pourrait être tenté de déréférencer le pointeur et là, c'est le drame...
printf("%dn", *f());
Eric Levenez
Le 14/07/09 11:17, dans <4a5c4d87$0$17767$, « Richard Delorme » a écrit :
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
Et tu connais une plateforme où, dans mon exemple, la variable locale p est modifiée entre les 2 print ?
J'imagine bien une appli avec pleins de malloc où les adresses sont stockées dans des structures, et un free fait que de façon immédiate quelque chose change tous les pointeurs des structures pour rendre "indéterminé" ces mêmes pointeurs.
mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
Oui, il n'y a pas d'intérêt, et c'est peut-être pour cela que la norme possède la phrase floue que tu cites. Ce fameux principe de précaution qui permet tous les excès.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 14/07/09 11:17, dans <4a5c4d87$0$17767$ba4acef3@news.orange.fr>,
« Richard Delorme » <abulmo@nospam.fr> a écrit :
Donc d'après toi le code précédent ne va pas afficher 2 fois la même
chose
et une opération magique va changer la valeur de la variable locale p au
moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du
pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the
object it points to reaches the end of its lifetime.
Et tu connais une plateforme où, dans mon exemple, la variable locale p est
modifiée entre les 2 print ?
J'imagine bien une appli avec pleins de malloc où les adresses sont stockées
dans des structures, et un free fait que de façon immédiate quelque chose
change tous les pointeurs des structures pour rendre "indéterminé" ces mêmes
pointeurs.
mais en
pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas
déférencer (sauf comme borne d'un tableau).
Oui, il n'y a pas d'intérêt, et c'est peut-être pour cela que la norme
possède la phrase floue que tu cites. Ce fameux principe de précaution qui
permet tous les excès.
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
Et tu connais une plateforme où, dans mon exemple, la variable locale p est modifiée entre les 2 print ?
J'imagine bien une appli avec pleins de malloc où les adresses sont stockées dans des structures, et un free fait que de façon immédiate quelque chose change tous les pointeurs des structures pour rendre "indéterminé" ces mêmes pointeurs.
mais en pratique, je ne vois pas l'intérêt d'un pointeur que l'on ne peut pas déférencer (sauf comme borne d'un tableau).
Oui, il n'y a pas d'intérêt, et c'est peut-être pour cela que la norme possède la phrase floue que tu cites. Ce fameux principe de précaution qui permet tous les excès.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
J'imagine que ça peut être effectif pour un pointeur qui serait un offset par rapport à un "truc" qui changerait, ou une entrée dans une table. A ce moment-là l'affichage par %p risque de foirer. Mais la variable pointeur (ou celle contenant une copie de sa valeur dans l'exemple initial) a toujours une valeur numérique qu'on peut afficher en castant en intptr_t ou uintptr_t. Effectivement ça ne sert à priori pas à grand-chose, ou alors dans une démarche de débogage ?
Donc d'après toi le code précédent ne va pas afficher 2 fois la même
chose
et une opération magique va changer la valeur de la variable locale p au
moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur
devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object
it points to reaches the end of its lifetime.
J'imagine que ça peut être effectif pour un pointeur qui serait un
offset par rapport à un "truc" qui changerait, ou une entrée dans une
table. A ce moment-là l'affichage par %p risque de foirer. Mais la
variable pointeur (ou celle contenant une copie de sa valeur dans
l'exemple initial) a toujours une valeur numérique qu'on peut afficher
en castant en intptr_t ou uintptr_t. Effectivement ça ne sert à priori
pas à grand-chose, ou alors dans une démarche de débogage ?
Donc d'après toi le code précédent ne va pas afficher 2 fois la même chose et une opération magique va changer la valeur de la variable locale p au moment du free ?
D'accord, printf affichera la même chose les deux fois,
En fait, ce n'est même pas obligé. D'après la norme, la valeur du pointeur devient indéterminé quand l'objet qu'il pointe n'existe plus.
§ 6.2.4.2 [...] The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
J'imagine que ça peut être effectif pour un pointeur qui serait un offset par rapport à un "truc" qui changerait, ou une entrée dans une table. A ce moment-là l'affichage par %p risque de foirer. Mais la variable pointeur (ou celle contenant une copie de sa valeur dans l'exemple initial) a toujours une valeur numérique qu'on peut afficher en castant en intptr_t ou uintptr_t. Effectivement ça ne sert à priori pas à grand-chose, ou alors dans une démarche de débogage ?