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

retourner une variable local (de type char[])

15 réponses
Avatar
matt
Bonjour,

voici une fonction retournant un pointeur sur un char.

char* mafonction()
{
char chaine[20];
strcpy(chaine, "Boujour");
return chaine;
}

c'est pas beau !!!
mais si on copie directement le retour de la fonction dans un autre
tableau de char :

int main()
{
char contenant[20];
strcpy(contenant, mafonction());
return 0;
}

est ce qu'il y a danger que le contenu de chaine soit modifié ?
et une autre question : ou est la différence avec le code suivant

int mafonction()
{
int retour;
retour = 10;
return retour;
}

int main()
{
int contenant;
contenant = mafonction();
return 0;
}

merci pour vos réponses,

Matt.

5 réponses

1 2
Avatar
Eric Levenez
Le 11/03/07 21:34, dans <45f467cb$0$25914$, « matt »
a écrit :

et ceci est ce correct ?

char* mafonction()
{
return "HELLO";
}


Oui, la chaîne est allouée par le compilateur qui la place généralement dans
une section en lecture seule de l'espace mémoire. Mais on tout cas la chaîne
n'est pas en pile et son adresse est une constante.

Un "const char *" aurait été meilleur.

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

Avatar
Pierre Maurette
Merci pour vos réponses...

une dernière question :

et ceci est ce correct ?

char* mafonction()
{
return "HELLO";
}


Non, ce n'est pas correct. "HELLO" est une constante littérale, ici un
const char*. Un compilateur coopératif de qualité devrait warner.

const char* mafonction()
{
return "HELLO";
}

serait "correct". Mais sans intérêt. Par rapport à:
const char* mafonction = "HELLO";

--
Pierre Maurette

Avatar
espie
In article <45f445f5$0$5084$,
Sylvain wrote:
Eric Levenez wrote on 11/03/2007 18:06:

Ce code n'utilise pas la pile mais le code de retour de la fonction. C'est
le principe même d'un code de retour.


euh, le code de retour est posé sur la pile soit mais comme l'est
sûrement le tableau non statique utilisé en paramètre local; la
différence est que l'appelant s'attend dans ce second cas à trouver
cette valeur de retour et la dépile correctement (préserve cette pile
avant de récupérer cette valeur) - dans le premier cas il dépile et
préserve l'adresse du tableau (et elle seule, non l'espace stockant son
contenu) ... une interruption et boum, comme tu l'as expliqué.

le C sait aujourd'hui retourner une structure, pour cela le compilo peut
utiliser la pile pour stocker le résultat complet.


T'as regarde le code produit par un compilo, parfois ? C'est quoi
l'architecture bizarre pour laquelle tu compiles ?

Pour ta gouverne, les valeurs de retour de fonction sont le plus souvent
deposees dans un registre.

Dans le cas particulier des retours de structure, c'est encore un peu
plus gore: pour les petites structures, elles sont retournees dans plusieurs
registres. Sinon, la fonction ne retourne rien, c'est l'appelant qui passe
l'adresse ou stocker la structure a la fonction.

Par exemple, sur i386, une fonction qui remplit une structure d'entier a
2 elements:
f:
pushl %ebp
movl %esp, %ebp
movl $5, %eax
movl $3, %edx
leave
ret



La meme avec 3 elements:
f:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl $5, (%eax)
movl $3, 4(%eax)
movl $15, 8(%eax)
leave
ret $4


Avatar
Sylvain
Marc Espie wrote on 12/03/2007 02:08:

T'as regarde le code produit par un compilo, parfois ? ...


oui pourquoi ? ça a un lien avec la question ?

Pour ta gouverne, les valeurs de retour de fonction sont le plus souvent
deposees dans un registre.


je sais.

Dans le cas particulier des retours de structure, c'est encore un peu
plus gore: pour les petites structures, elles sont retournees dans plusieurs
registres. Sinon, la fonction ne retourne rien, c'est l'appelant qui passe
l'adresse ou stocker la structure a la fonction.


je sais aussi.

merci quand même.

Sylvain.

Avatar
Sylvain
Eric Levenez wrote on 11/03/2007 21:24:

euh, le code de retour est posé sur la pile
Normalement non. Peut-être que l'on peut trouver une architecture où ce que

tu dis est vrai, mais en règle générale le code de retour est dans un
registre du CPU, pas dans la pile.


:) j'ai voulu faire court et tu as raison ce que j'ai formulé est erroné
- je ne connais pas non plus de compilo n'utilisant pas l'accu.

soit mais comme l'est
sûrement le tableau non statique utilisé en paramètre local;
La tableau est dans un espace qui n'existe que DANS la fonction, pas à

l'extérieur, et là, effectivement, c'est généralement la pile.


à l'exterieur (de l'un qui est sûrement l'intérieur d'un autre) "ça"
s'appelle toujours la pile.

différence est que l'appelant s'attend dans ce second cas à trouver
cette valeur de retour et la dépile correctement (préserve cette pile
avant de récupérer cette valeur) - dans le premier cas il dépile et
préserve l'adresse du tableau (et elle seule, non l'espace stockant son
contenu) ... une interruption et boum, comme tu l'as expliqué.


Conclusion basée sur des fausses hypothèses.


non pas fausses hypothèses, disons plutôt (très) mauvaise formulation -
je pensais pour le premier cas à un retour d'entier évalué via des
opérandes locaux donc sur la pile (si tout ne tient pas en registre, le
résultat final lui y étant au moment du retour).

par contre où as-tu lu une "conclusion", ou si c'est le statut que tu
donnes au fait que le char[] local est réservé sur la pile, peux-tu
détailler ce qui serait faux ? des réponses ont utilisés les terme
"tableau alloué" qui "est désalloué lors du retour de la fonction", je
préfère franchement parler de simple incrémentation du pointeur de pile.

le C sait aujourd'hui retourner une structure, pour cela le compilo peut
utiliser la pile pour stocker le résultat complet.


Oui, le C peut retourner une structure, mais ce n'est pas dans le cas d'une
variable automatique, même si c'est une structure.

Et pour info, sur certaines architectures les petites structures sont
retournées dans des registres et pas dans la pile.


oui et non, l'appelant peut monter la pile avant appel; je n'avais pas
dit "l'appellé pollue la pile et nique le ret n", juste le résultat
transite par la pile.

Sylvain.


1 2