5 votes

Comment les listes d'arguments de longueur variable sont-elles implémentées ?

Que se passe-t-il en interne lorsqu'une fonction qui utilise des varargs est appelée ? Les arguments eux-mêmes sont-ils stockés sur le tas ou sur la pile comme tout autre argument ? S'ils sont sur la pile, comment cela fonctionne-t-il ?

8voto

Oli Charlesworth Points 148744

Cela dépend de la mise en œuvre. Mais très probablement, les args sont placés sur la pile, l'un après l'autre (après que les promotions d'arguments par défaut aient été effectuées).

va_start , va_arg etc. fonctionnent en promenant simplement un pointeur dans la pile, et en réinterprétant les bits comme le type que vous demandez.

5voto

cha0site Points 5675

Comme on l'a déjà noté, cela dépend de l'implémentation.

Dans la convention d'appel du C (connue sous le nom de cdecl ), les arguments sont poussés dans la pile dans l'ordre inverse, donc :

void myfunc(int one, int two, int three)

ressemblera à ceci sur la pile après qu'il ait été appelé (la pile grandit vers le haut, vers 0) :

  .                .                0x00000000
  .                .
  .                .
  | current frame  |
  |----------------|
  | return address |
  |----------------|                   ^
  |    one         |                   | stack
  |----------------|                   | growth
  |    two         |                   | direction
  |----------------|                   |
  |    three       |
  |----------------|
  | previous frame |
         ...       
         ...                        0xFFFFFFFF

Ainsi, le premier argument peut être récupéré en premier (car nous connaissons son emplacement, il est juste avant l'adresse de retour), et avec un peu de chance, il contient suffisamment d'informations sur le nombre d'autres arguments présents. Par exemple, dans printf(3) et les fonctions connexes, toutes les informations sur les autres arguments sont présentes dans la chaîne de format, qui est le premier argument.

1voto

Eser Aygün Points 2340

En C, les arguments des fonctions sont à la fois poussés sur la pile et retirés de celle-ci par la fonction appelante. La fonction appelante sait combien d'éléments ont été poussés et elle est donc également capable de les retirer après l'appel. Le destinataire de l'appel peut uniquement déduire le nombre d'arguments à partir d'autres paramètres, comme la chaîne de format de la fonction printf() .

En Pascal, par exemple, les arguments sur la pile sont tirés par le destinataire de l'appel. Comme le destinataire n'est pas conscient du nombre d'éléments poussés, il ne peut pas non plus restaurer la pile à son état précédent. C'est pourquoi il est impossible d'implémenter les varargs en Pascal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X