OVH Cloud OVH Cloud

Necessite d'utiliser l'argument sur la pile

17 réponses
Avatar
noirel
Bonjour,

Si une fonction est définie pour recevoir un nombre variable
d'arguments, est-elle obligée d'utiliser tous ses arguments ?
La raison de cette question est que dans une telle fonction l'argument
peut ne pas servir effectivement dans certaines conditions.

int fonction ( const unsigned int entier, ... )
{
/* ... */
switch ( entier ) {
case FOO:
if ( ... ) {
/* Faire quelque chose avec va_arg ( ... ) */
} else {
unsigned int junk = va_arg ( ... ); /* Est-ce nécessaire ? */
fprintf ( stderr, "No more room...\n" );
/* ... */
}
}
/* ... */
}

La ligne

unsigned int junk = va_arg ( ... );

est-elle nécessaire ?

--
Joss

7 réponses

1 2
Avatar
Alexandre BACQUART
Horst Kraemer wrote:
void f(int n, ...)
{
int i1,i2;
va_list ap;

va_start(ap,n);
(void)va_arg(ap,int);
i2=va_arg(ap,int);
va_end(ap);

va_start(ap);
i1=va_arg(ap,int);
va_end(ap);
}

scnr

Y a-t-il une facon illégale d'utiliser les arguments non
séquentiellement ?


Qu'entends-tu par "illégal" précisément ?

En dehors de ton exemple (à ne pas suivre bien-sûr, je ne suis même pas
sûr que la norme autorise explicitement l'utilisation de va_start() plus
d'une fois, même si ça marche, et puis ça ne sert au fond qu'à ralentir
le programme), il y a les directives asm{}. C'est toujours légal, mais
ce n'est plus du C.



--
Tek

Avatar
noirel
Emmanuel Delahaye , a écrit ceci :
La norme n'a pas répondu à mes questions donc je demande conseil ici
plutôt que d'attendre que ça buggue pour me manifester, parce que je
suis un peu suspicieux vis à vis de ce que je produis et lis la norme
avec autant de parcimonie que possible. :-)


A mois qu'il y ait un problème de vocabulaire, et que tu veuilles dire 'avec
autant d'attention' ou 'autant de précision'.


Non c'est bien parcimonie que je voulais utiliser.

Pourtant, la lecture de la norme mérite plus que de la parcimonie.


Sans doute, en l'état actuel des choses (qui tient à mon boulot, mon
niveau de programmation en C, mon temps disponible et mes goûts
littéraires) je trouve que c'est une lecture déplaisante. Mais dans le
principe tu as raison, bien sûr.

--
Joss


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Horst Kraemer wrote:

Non. Mais si ils sont utilisés, ils doivent l'être séquentiellement en
partant du plus à gauche.


void f(int n, ...)
{
int i1,i2;
va_list ap;

va_start(ap,n);
(void)va_arg(ap,int);
i2=va_arg(ap,int);
va_end(ap);

va_start(ap);
i1=va_arg(ap,int);
va_end(ap);
}

scnr

Y a-t-il une facon illégale d'utiliser les arguments non
séquentiellement ?


Illégale, oui, mais légale non.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Avatar
Alexandre BACQUART
Josselin Noirel wrote:

Anthony Fleury , a écrit ceci :

Il n'est pas obligatoire d'utiliser tous les arguments d'une fonctionn
normale, c'est la même chose pour les fonctions à nombre d'arguments
variable.



Bon, ben voilà, j'ai ma réponse. La différence que je _vois_ entre les
deux types de fonction c'est que la dernière nécessite d'aller chercher
explicitement ses arguments (je souligne « vois » parce que mes yeux ne
sont pas experts) et que n'allant pas les chercher je me demandais si ça
ne laissait pas le bazar d'une façon ou d'une autre (pour faire une
analogie fallacieuse, comme si on omettait de faire un wait()).


Normallement, les macros va_start()... va_end() ne devraient en rien
affecter le fonctionnement interne de la pile, que tu les utilises mal,
ou pas (elles ne te donnent pas d'autre choix que de travailler avec des
copies).

Par ex., chez moi, l'oubli du va_end() après va_start() (qui est une
erreur au sens de la norme) n'empêche pas le programme de fonctionner.
Ce n'est pas forcément sans surprise, il y a peut-être des
implémentations où l'oubli de va_end() met le foutoir, mais on peut
affirmer que l'absence totale d'utilisation des va_*() ne fera rien de mal.


--
Tek


Avatar
Horst Kraemer
On Mon, 31 May 2004 09:07:54 +0200, Alexandre BACQUART
wrote:

Horst Kraemer wrote:
void f(int n, ...)
{
int i1,i2;
va_list ap;

va_start(ap,n);
(void)va_arg(ap,int);
i2=va_arg(ap,int);
va_end(ap);

va_start(ap);
i1=va_arg(ap,int);
va_end(ap);
}

scnr

Y a-t-il une facon illégale d'utiliser les arguments non
séquentiellement ?


Qu'entends-tu par "illégal" précisément ?


C'est justement cette question que je voulais poser par "Y a-t-il une
facon illégale d'utiliser les arguments non séquentiellement ?"

--
Horst


Avatar
Yves ROMAN

Par ex., chez moi, l'oubli du va_end() après va_start() (qui est une
erreur au sens de la norme) n'empêche pas le programme de fonctionner.
Ce n'est pas forcément sans surprise, il y a peut-être des
implémentations où l'oubli de va_end() met le foutoir, mais on peut
affirmer que l'absence totale d'utilisation des va_*() ne fera rien de mal.



J'allais demander s'il existait vraiment des implémentation ou va_end() était
autre chose qu'une macro vide, et en regardant sur mon système j'ai trouvé une
chose curieuse dans varargs.h:

extern void va_end(va_list);
#define va_end(list) (void)0

Quel peut être l'intérêt du prototype , sachant que la fonction ne sera jamais
appelée à cause de la macro ?

A part, après réflexion, à avoir l'adresse de cette fonction fantôme va_end() ?

Avatar
Alexandre BACQUART
Yves ROMAN wrote:
J'allais demander s'il existait vraiment des implémentation ou va_end() était
autre chose qu'une macro vide,


Oui. Sur la plupart des sytèmes, va_end() ne fait rien, mais tu peux
être sûr que l'oublier là où il fait quelque-chose fera planter ton
programme.


--
Tek

1 2