va_arg返回值警告的标准C类型

时间:2011-12-13 15:14:21

标签: c variadic-functions

我正在开发一个C程序并且被这个警告所困扰。我想使用va_arg从列表中检索参数。

args[i] = (int) va_arg(argptr, int); 

args[i] = (char) va_arg(argptr, char);

收到此警告的问题:

... void *' differs in levels of indirection from 'int'...

同样也适用于char案例。 对此有何解释?

代码:

void test_function(va_list argptr, int (*callback)(),
                   int ret_typel)
{
  int i ;
  int arg_typel;
  int no_moreb = TRUE;
  void *args[MAX_FUNCTION_ARGS];
  for (i=0; no_moreb; i++) {
    arg_typel = (int)va_arg(argptr, int);
    switch(arg_typel) {
    case F_INT:
      args[i] = (int) va_arg(argptr, int);
      break;
    case F_CHAR:
      args[i] = (char) va_arg(argptr, char);
      break;
    default:
      no_moreb = FALSE;
      i--;
      break;
    }
  }
}

4 个答案:

答案 0 :(得分:10)

有关使用va_arg()的详细信息。

你不能使用:

va_arg(argptr, char);

不调用未定义的行为(错误!)。 varargs函数的变量参数经过促销:float传递为doublecharunsigned charsigned charshort,{ {1}}根据需要升级到unsigned shortint。因此,您永远不能直接使用unsigned (int)提取char;您只能指定推广类型。你必须写:

va_arg

这一次,施法是由于作业而发生的;说它与演员一起发生并不是绝对必要的,但没有坏处(虽然我可能不会在我自己的代码中编写演员表)。

答案 1 :(得分:3)

问题是args[]void *的数组。您无法将intfloat分配给void *(这没有任何意义)。你可以通过施法来解决这个问题,但这不是一个好主意。

如果要在同一个变量中存储不同的类型,请考虑使用union:

typedef union
{
    char  c;
    int   i;
    float f;
} MyUnion;

MyUnion args[MAX_FUNCTION_ARGS];

args[i].c = va_arg(argptr, char);
args[i].i = va_arg(argptr, int);
args[i].f = va_arg(argptr, float);

<强>更新 正如Jonathan Leffler在答案中正确指出的那样,由于可变函数的默认促销,不应使用va_arg(argptr, char)va_arg(argptr, float)

答案 2 :(得分:3)

数组argsvoid *的数组。您可以为它指定普通整数,这就是您收到错误的原因。

答案 3 :(得分:0)

您正在传递一个void指针,并且您将指针转换为int或char。您需要取消引用void指针然后强制转换,或者先将其转换为(int *)或(char *)。