【问题标题】:How does gcc (x64) deal with types/sizes in variadic functions?gcc (x64) 如何处理可变参数函数中的类型/大小?
【发布时间】:2018-04-13 11:13:58
【问题描述】:

可变参数函数和 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 

怎么做?

【问题讨论】:

    标签: c gcc variadic


    【解决方案1】:

    可变参数函数的参数在 linux x64 上“提升”为 64 位值,因此无需在此平台上显式转换为 64 位值。

    【讨论】:

      【解决方案2】:

      使其工作的基本代码是

      x = va_arg(ap, long);
      

      您可以通过将其更改为任何其他类型来很好地射中自己的脚。

      char ch = va_arg(ap, char);
      

      根据目标架构的规则,这可能会在每次访问后将 ap 增加一、二、四或八。

      【讨论】:

      • 但 f() 被传递为整数(x64 上为 32 位)。我刚刚在stackoverflow.com/questions/49814318/…
      • 从逻辑上讲,ap 会增加 (sizeof long) 或 (sizeof char) - 但我知道情况并非如此
      猜你喜欢
      • 2011-01-26
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 2022-06-14
      • 1970-01-01
      • 2019-08-28
      • 2011-01-30
      相关资源
      最近更新 更多