2012-06-30 22 views
14

Tengo una función variadica que toma un parámetro flotante. ¿Por qué no funciona?La función variable (va_arg) no funciona con float?

va_arg(arg, float) 
+0

Se puede publicar la función completa? – Jack

+9

Tienes suerte de que hayas podido obtener una respuesta que probablemente sea correcta, dado el poco contexto que proporcionaste. Tenga en cuenta que la respuesta es "libro de texto" ... es decir, está disponible para cualquier persona que lea la documentación apropiada (por ejemplo, man stdarg). –

+0

Tiene usted razón, la información se encuentra en la documentación de stdarg. No me di cuenta antes. –

Respuesta

37

parámetros de las funciones que corresponden a ... son promovidos antes de pasar a la función variadic. char y short son promovidos a int, float es promovido a double, etc.

6.5.2.2.7 La notación de puntos suspensivos en un prototipo de función declarador causa argumento de conversión de tipo para detenerse después del último parámetro declarado. Las promociones de argumento predeterminado se realizan en argumentos finales.

La razón de esto es que las primeras versiones de C no tenían prototipos de funciones; los tipos de parámetros se declararon en el sitio de la función pero no se conocían en el sitio de la llamada. Pero los diferentes tipos se representan de manera diferente, y la representación del argumento pasado debe coincidir con la expectativa de la función llamada. Para que los caracteres y los valores cortos se pasen a las funciones con parámetros int, o los valores float se pueden pasar a las funciones con parámetros dobles, el compilador "promovió" los tipos más pequeños para que sean del tipo más grande. Este comportamiento aún se ve cuando el tipo de parámetro no se conoce en el sitio de llamada, es decir, para funciones variadas o funciones declaradas sin un prototipo (por ejemplo, int foo();).

+0

Tengo una pregunta sobre eso, porque acabo de tener el mismo problema. Escuché que 'printf' también promueve' float' a 'double', pero' printf' usualmente funciona bien para mí. ¿Cuál es la diferencia entre estos dos casos? – Kusavil

+1

@Kusavil Si tiene una pregunta de seguimiento, sería mejor que publicara una nueva pregunta (podría hacer referencia a esta pregunta en su publicación). Describe tu problema y muestra el código problemático. Esto le daría más respuestas que solo una, y tendría un mayor potencial de ser útil a los demás que un comentario sobre una vieja pregunta. – dasblinkenlight

+0

@ dasblinkenlight bien, publiqué mi propia pregunta :) No estoy seguro si es una buena pregunta, aunque mi forma de percibir y comprender las cosas aquí es deficiente en muchos aspectos, pero si alguien estuviera interesado, esta es mi pregunta: http: // stackoverflow. com/questions/23836118/variadic-function-va-arg-doesnt-work-with-float-while-printf-does-what-the – Kusavil

9

Como @dasblinkenlight ha mencionado, flotador es promocionado a doble. Funciona bien para mí:

#include <stdio.h>   
#include <stdarg.h> 

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; 
} 

Salida:

3.300000 
4.400000 
+4

Tenga en cuenta que '3.3' y' 4.4' son constantes del tipo 'double' - para mostrar que' float' se promueve, debe usar '3.3f' y' 4.4f'. – caf

+0

@caf Apenas me gané. :) –

+1

Gracias. Editado :) – Jack

Cuestiones relacionadas