2010-01-08 5 views
2

Le compilateur produira-t-il le même code pour ces deux instructions?c/C++ passant argument par pointeur/argument par mise en page de la pile de référence

foo1(int* val){(*val)++;} 

foo2(int &val){val++;} 

aura-t-il simplement écrire un pointeur dans la partie des paramètres du cadre de pile de foo? Ou, dans le second cas, les trames de pile des appelants et des assistants vont-elles se chevaucher de telle sorte que la variable locale des appelants prenne la même mémoire sur la pile que le paramètre pour foo?

+0

Doit être exactement identique. En cas de doute sur ces cas, mieux vaut vérifier le démontage. – Andy

Répondre

0

Les piles ne peuvent pas se chevaucher. Considérons que l'argument peut être global, un objet tas, ou même s'il est stocké dans la pile, il pourrait ne pas être le dernier élément. Selon la convention d'appel, d'autres éléments peuvent être placés entre une trame de pile et les paramètres passés dans la fonction (ie adresse de retour) ...

Et notez que même si rien n'a été ajouté dans la pile, la décision ne peut pas être faite lors de la compilation de la fonction, mais plutôt lorsque le compilateur traite la fonction appelante. Une fois la fonction compilée, elle ne changera pas selon l'endroit d'où elle est appelée.

+0

Je pense que la mention de linker inlining pourrait ne pas aller à des amis pour cette question. –

4

Ces deux appels doivent générer exactement le même code, sauf si vous avez un type de compilateur bizarre.

2

Cela dépend.

Le code généré pour les deux sera équivalent sinon identique sur la plupart des plates-formes s'il est compilé dans une bibliothèque. Tout bon compilateur mettra en ligne une si petite fonction, il est donc tout à fait possible qu'au lieu d'obtenir l'adresse de quelque chose sur la pile en incrémentant la valeur pointée, il va plutôt incrémenter la valeur directement. Tout cadre de pile de la fonction inline est incorporé dans le cadre de la pile de l'appelant, de sorte que le testament se chevauchera dans ce cas.

+0

donc aussi la version qui prend un pointeur serait inline et au lieu de travailler avec un pointeur, travaillerait directement sur la variable réelle? – Mat

+0

@Mat: La version de référence peut également être en ligne. –

+0

@Mat: les deux peuvent être en ligne pour fonctionner directement sur la variable réelle. –

0

en ce qui concerne le chevauchement des cadres de pile, je trouve les informations suivantes here :

Pour certaines applications, le cadre de la pile d'un sous-programme et celui de son appelant peut être considéré comme chevaucher, le recouvrement constitué de la zone où la les paramètres sont passés de l'appelant à l'appelé. Dans certains environnements, l'appelant pousse chaque argument sur la pile, étendant ainsi son cadre de pile, puis invoque l'appelé. Dans d'autres environnements, l'appelant a une zone préallouée en haut de son cadre de pile pour contenir les arguments qu'il fournit à d'autres sous-programmes qu'il appelle. Cette zone est parfois appelée zone d'arguments sortante ou zone de légende. Selon cette approche, la taille de la zone est calculée par le compilateur comme étant la plus grande requise par n'importe quel sous-programme appelé. Donc, dans votre cas, si seules les variables dans les étendues locales des fonctions de l'appelant sont transmises à foo2, une chose qui se chevauche peut être possible!

Questions connexes