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

Fonction variadique qui n'utilise pas ses arguments.

5 réponses
Avatar
Erwan David
J'ai besoin de faire une fonction variadique qui n'utilise pas ses
arguments, du genre

void f(char * msg,...)
{
return;
}

Avec un compilateur un peu étrange, mais globalement C Iso (pas 99).

Est-ce que ça doit marcher ? (j'ai regardé l'assembleur produit, ça
devrait marcher dans ce cas là, mais ce n'est qu'un test non concluant).

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé

5 réponses

Avatar
Antoine Leca
En news:, Erwan David va escriure:
J'ai besoin de faire une fonction variadique qui n'utilise pas ses
arguments, du genre

void f(char * msg,...)
{
return;
}

Est-ce que ça doit marcher ?


La manière officielle (et sûre), c'est d'écrire

void f(char * msg,...)
{ va_list ap;
va_start(ap, msg);
va_end(ap);
return;
}

Maintenant, je suppose que cela signifie un surcoût que tu souhaiterais
éviter...

Je n'ai rien lu dans la norme qui autorise un fonctionnement erroné («
comportement indéfini ») si on omet les deux appels (par contre, omettre
va_end() expose à un comportement indéfini). La phrase qui tue est 7.8.1.1p2
(C99 7.15.1.4p2):
The va_start macro shall be invoked before any access to the
unnamed arguments.
Donc il est probable que cela doit officiellement fonctionner.
SAUF bogue du compilateur. Par exemple, si celui qui implémente lit de
travers et s'est arrêté au milieu de la phrase ("shall be invoked"<point>),
et donc prétend que ne pas faire l'appel engendre un comportement
indéfini...


Par ailleurs, si le compilateur utilise l'implémentation classique de
va_start (avec va_end qui ne fait rien), tu peux y aller sans crainte...


Antoine

Avatar
Aris
En news:, Erwan David va escriure:
J'ai besoin de faire une fonction variadique qui n'utilise pas ses
arguments, du genre

void f(char * msg,...)
{
return;
}
Je pense meme qu'il n'y a pas besoin de ça, en fait


void f(){
return;
}
est censé accepter un nombre infini de parametres (d'ailleur on se
permet souvent d'écrire void main() )
c'est un héritage du début du c, je ne sais pas si c'est encore accepté
par c99


Avatar
Erwan David
"Antoine Leca" écrivait :

En news:, Erwan David va escriure:
J'ai besoin de faire une fonction variadique qui n'utilise pas ses
arguments, du genre

void f(char * msg,...)
{
return;
}

Est-ce que ça doit marcher ?


La manière officielle (et sûre), c'est d'écrire

void f(char * msg,...)
{ va_list ap;
va_start(ap, msg);
va_end(ap);
return;
}

Maintenant, je suppose que cela signifie un surcoût que tu souhaiterais
éviter...

Je n'ai rien lu dans la norme qui autorise un fonctionnement erroné («
comportement indéfini ») si on omet les deux appels (par contre, omettre
va_end() expose à un comportement indéfini). La phrase qui tue est 7.8.1.1p2
(C99 7.15.1.4p2):
The va_start macro shall be invoked before any access to the
unnamed arguments.
Donc il est probable que cela doit officiellement fonctionner.
SAUF bogue du compilateur. Par exemple, si celui qui implémente lit de
travers et s'est arrêté au milieu de la phrase ("shall be invoked"<point>),
et donc prétend que ne pas faire l'appel engendre un comportement
indéfini...


Par ailleurs, si le compilateur utilise l'implémentation classique de
va_start (avec va_end qui ne fait rien), tu peux y aller sans crainte...


Ok, merci.

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé


Avatar
Erwan David
Aris écrivait :

En news:, Erwan David va escriure:
J'ai besoin de faire une fonction variadique qui n'utilise pas ses
arguments, du genre

void f(char * msg,...)
{
return;
}
Je pense meme qu'il n'y a pas besoin de ça, en fait


void f(){
return;
}
est censé accepter un nombre infini de parametres (d'ailleur on se
permet souvent d'écrire void main() )
c'est un héritage du début du c, je ne sais pas si c'est encore
accepté par c99


Vu que mon compilateur fait aussi du C++, je préfère éviter le C
pré-ANSI. d'autant que c'est contre les règles de codage du projet.


--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé



Avatar
Antoine Leca
En news:478e9a54$0$32000$, Aris va escriure:
void f(){
return;
}
est censé accepter un nombre infini de parametres


Je suppose que dans un autre endroit de ton projet, tu as

void f(char *,...);
f(a,b,c);

et dans un troisième endroit

void f(char *,...);
f(z);


Peut être que cela marche avec ton compilateur, mais ce n'est pas universel
(ou alors j'ai mal lu la partie de la norme à ce sujet).


(d'ailleur on se permet souvent d'écrire void main() )


1) si tu ne veux pas te faire tirer les oreilles, écris int main()
2) main est un cas particulier, d'ailleurs beaucop de compilateurs (pas
seulement C/C++) repèrent spécifiquement main
3) si tu écris

exitcode = main(argc, argv, envp, toto);

ce n'est plus du code conforme à mon interprétation de la norme, même si
cela marche avec ton compilateur.


c'est un héritage du début du c, je ne sais pas si c'est encore
accepté par c99


À mon sens tu confonds deux notions, l'une étant les définitions « ancien
style » (K&R), sans prototypes ni contrôle de la signature ; et par ailleurs
les fonctions variadiques, à nombre variable d'arguments.
Dans la norme ANSI (y compris le projet de 1986), les secondes sont
incompatibles avec les premières, autrement dit une fonction à nombre
variable d'arguments doit toujours avoir un prototype, et sa définition doit
intégrer les points de suspension ; cela permet à certains compilateurs
d'utiliser des conventions d'appel différentes (et donc d'utiliser des
conventions d'appel plus efficaces, passant les paramètres par registres,
pour les fonctions qui ont un nombre défini de paramètres). Évidemment C99
ne change rien à cet ordre établi.

Certains compilateurs (dont GCC si mes souvenirs sont bons), qui ont des
conventions d'appel différentes pour les fonctions variadiques, repèrent
spécifiquement les appels à printf() et quelques autres et insèrent le
prototype automatiquement, pour permettre de compiler d'anciens programmes ;
mais ce n'est pas du code conforme.


Antoine