Ответ 1
Он не дифференцируется. Невозможно получить float
как vararg: любой аргумент float
, который вы предоставляете, сначала рекламируется до double
.
6.5.2.2/6 определяет "поощрения по умолчанию для аргументов по умолчанию" и /7 указывает, что промо-объявления по умолчанию применяются к "конечным аргументам", то есть varargs, обозначенным как ...
.
как это работает для scanfs/sscanf?
Для формата %f
для scanf
требуется указатель на float
. %lf
требуется указатель на double
, %lf
требуется указатель на long double
.
копирование значения в temp и casting (это правильно?)
Если вы предоставляете аргумент float, тогда реализация создает временный тип double, инициализирует его значением float и передает это как vararg. Кастинг по определению - это явное преобразование с помощью оператора трансляции - вы можете использовать, если хотите, чтобы он четко дал понять читателю, что происходит, но float f = 3; printf("%f", f);
точно совпадает с float f = 3; printf("%f", (double)f);
. Продвижение аргументов по умолчанию имеет то же значение, что и приведение.