9
votes

C ++ Renvoi de renvoi / mémoire de pile

Une question fondamentale que je ne suis pas sûre de la réponse. La fonction Suivre est-elle valide? XXX

Si oui, pourquoi? Le programme ne devrait-il pas supprimer x de la pile après que la fonction retourne? Merci.


0 commentaires

4 Réponses :


11
votes

Le comportement est indéfini. Vous ne devriez pas retourner des références aux variables locales.


1 commentaires

Le code montré ne contient pas (en soi) de comportement non défini. L'UB arriverait dans un autre code qui appelle cette fonction.



9
votes

La fonction est bien formée (syntaxiquement correcte), mais dès que la fonction renvoie, la référence renvoyée n'est pas valide et ne peut pas être utilisée.

Pour clarifier: le code en question pas invoquer tout comportement non défini. Vous pouvez appeler cette fonction aussi longtemps que vous n'utilisez pas la valeur de retour, par exemple, ceci est valide: xxx

Cependant, si vous essayez d'utiliser la valeur de retour (c.-à-d. , initialiser une autre référence avec elle ou copier le référent dans un autre objet), vous invoquerez un comportement non défini car la durée de vie du référent (l'objet x ) sera terminé ( x sera détruit lorsque la fonction renvoie parce qu'il s'agit d'une variable automatique): xxx


3 commentaires

Sur une note sérieuse, si la structure étant référencée est juste un tas de gousses (aucun pointeur) ou est une primitive, si le cadre de pile normal est maintenu et que vous copiez la valeur (pas une référence à votre deuxième exemple. Ici), la valeur locale d'origine ira bien immédiatement après le retour ( MOV ESP, EBP; POP EBP; Cadre de pile local n'est pas perturbé). Cependant, les destructeurs sont invoqués et les données peuvent être manipulées / modifiées. C'est la mauvaise façon d'y aller à ce sujet, cependant et de prédire ce qui se passera, même si cela devinait avec précision au même endroit n'est pas portable.


@jmerlin: Même pour un objet de type POD, les résultats sont formellement indéfinis. La durée de vie d'une cosse se termine lorsque sa durée de stockage se termine; Pour une variable locale, cela est au point que la fonction revient. L'utilisation d'un objet après sa vie est terminée, des résultats sont un comportement non défini. Est-ce que cela éventuellement "travailler" dans la pratique avec des objets de type POD? Peut-être, mais comme vous le dites, ce n'est pas un comportement qui devrait être invoqué.


Il ne devrait certainement pas être invoqué lorsque la multi-threading devient standard car l'emplacement du cadre de pile pouvait déjà avoir été réutilisé par un autre thread (note que la norme ne définit pas la mise en œuvre de la pile ou du tas).



0
votes

Vous ne pouvez pas renvoyer une référence à une variable locale pour la même raison pour laquelle vous ne pouvez pas renvoyer un pointeur à une variable locale, car le retour de la fonction que les variables locales sont traitées et que la référence ou le pointeur devient invalide.


0 commentaires

1
votes

Oui, c'est valide, mais si vous essayez d'utiliser la valeur renvoyée, vous obtiendrez un comportement indéfini.


0 commentaires