Функция Variadic (va_arg) не работает с float?

У меня есть вариационная функция, которая принимает параметр float. Почему это не работает?

va_arg(arg, float)

Ответы

Ответ 1

Параметры функции, соответствующие ..., продвигаются до перехода к вашей вариационной функции. char и short повышаются до int, float повышается до double и т.д.

6.5.2.2.7 Обозначение многоточия в деклараторе прототипа функции вызывает преобразование типа аргумента для остановки после последнего объявленного параметра. Аргумент по умолчанию рекламные акции выполняются по завершающим аргументам.

Причина этого в том, что ранние версии C не имели прототипов функций; типы параметров были объявлены на сайте функции, но не были известны на сайте вызова. Но разные типы представлены по-разному, и представление переданного аргумента должно соответствовать ожидаемому вызову функции. Чтобы char и короткие значения могли быть переданы функциям с параметрами int, или значения float могли быть переданы функциям с двойными параметрами, компилятор "продвигал" более мелкие типы с более крупным типом. Такое поведение все еще наблюдается, когда тип параметра неизвестен на сайте вызова, а именно: для вариативных функций или функций, объявленных без прототипа (например, int foo();).

Ответ 2

Как упоминал @dasblinkenlight, float повышается вдвое. Это отлично работает для меня:

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

Вывод:

3.300000
4.400000