La fonction variée (va_arg) ne fonctionne pas avec float?

J’ai une fonction variadic qui prend un paramètre float. Pourquoi ça ne marche pas?

va_arg(arg, float) 

Les parameters des fonctions qui correspondent à ... sont promus avant de passer à votre fonction variadique. char et short sont promus en int , float en double , etc.

6.5.2.2.7 La notation de points de suspension dans un déclarateur de prototype de fonction provoque l’arrêt de la conversion du type d’argument après le dernier paramètre déclaré. Les promotions d’argument par défaut sont effectuées sur les arguments de fin.

La raison en est que les premières versions de C n’avaient pas de prototypes de fonctions; les types de parameters ont été déclarés sur le site de la fonction mais n’étaient pas connus sur le site de l’appel. Mais différents types sont représentés différemment, et la représentation de l’argument passé doit correspondre à l’attente de la fonction appelée. Pour que les valeurs char et short puissent être passées aux fonctions avec les parameters int ou aux valeurs float pour les fonctions ayant deux parameters, le compilateur “promeut” les types les plus petits comme étant du type les plus grands. Ce problème persiste lorsque le type du paramètre n’est pas connu sur le site de l’appel, notamment pour les fonctions variadiques ou déclarées sans prototype (par exemple, int foo(); ).

Comme @dasblinkenlight l’a mentionné, float est encouragé à doubler . Ça fonctionne bien pour moi:

 #include  #include  void foo(int n, ...) { va_list vl; va_start(vl, n); int c; double val; for(c = 0; c < n; c++) { val = va_arg(vl, double); printf("%f\n", val); } va_end(vl); } int main(void) { foo(2, 3.3f, 4.4f); return 0; } 

Sortie:

 3.300000 4.400000