gcc (x64) 如何处理可变函数中的 types/sizes?

How does gcc (x64) deal with types/sizes in variadic functions?

可变参数函数和 main()

#include <stdio.h>
#include <stdarg.h>
int f(long x,...)
{ va_list ap;
  int i=0;
  va_start(ap,x);
  while(x)
  { i++;
    printf("%ld ", x);
    x=va_arg(ap,long);
  }
  va_end(ap);
  printf("\n");
  return i;
}

int main()
{ return f(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,1L<<63,0);
}

在 gcc、linux 和 x64 上:即使 f() 的参数未转换为 64 位长,gcc 似乎也正确。

$ gcc t.c && ./a.out
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -9223372036854775808 

怎么办?

可变参数函数的参数是 "promoted" 到 linux x64 上的 64 位值,因此无需在此平台上显式转换为 64 位值。

使它工作的基本代码是

x = va_arg(ap, long);

改成其他类型,你可以搬起石头砸自己的脚。

char ch = va_arg(ap, char);

根据目标体系结构的规则,这可能会在每次访问后将 ap 递增 1、2、4 或 8。