va_arg
не преобразует аргумент. интерпретирует как указанный тип. А если типы не совпадают, вы вызываете неопределенное поведение.
va_arg(ptr, int); /* take the next 4 bytes from the stack and interpret them as an `int` */
va_arg(ptr, double); /* take the next 8(?) bytes ... and interpret as double */
(int)va_arg(ptr, double); /* ... convert to int */
Также обратите внимание, что приведение в действительности не требуется в вашем фрагменте. Компилятор автоматически преобразует
void varfun(int n, ...) {
va_list ptr;
int num;
va_start(ptr, n);
num = va_arg(ptr, double); /* interpret as double, then convert to int */
printf("%d\n",num);
}