繁体   English   中英

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

[英]Standard C cast of va_arg return value warning

我正在开发一个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;
    }
  }
}

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

你不能使用:

va_arg(argptr, char);

没有调用未定义的行为(这很糟糕 !)。 varargs函数的变量参数经历了促销: float作为double传递, charunsigned charsigned charshortunsigned short根据需要进行升级到intunsigned (int) 因此,您永远不能使用va_arg直接提取char ; 您只能指定推广类型。 你必须写:

char c = (char) va_arg(argptr, int);
float f = (float) va_arg(argptr, double);

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

问题是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)

数组args是一个void *数组。 您为它分配纯整数,这是您得到错误的原因。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM