我正在开发一个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;
}
}
}
答案 0 :(得分:10)
有关使用va_arg()
的详细信息。
你不能使用:
va_arg(argptr, char);
不调用未定义的行为(错误!)。 varargs函数的变量参数经过促销:float
传递为double
,char
,unsigned char
,signed char
,short
,{ {1}}根据需要升级到unsigned short
或int
。因此,您永远不能直接使用unsigned (int)
提取char
;您只能指定推广类型。你必须写:
va_arg
这一次,施法是由于作业而发生的;说它与演员一起发生并不是绝对必要的,但没有坏处(虽然我可能不会在我自己的代码中编写演员表)。
答案 1 :(得分:3)
问题是args[]
是void *
的数组。您无法将int
或float
分配给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)
数组args
是void *
的数组。您可以为它指定普通整数,这就是您收到错误的原因。
答案 3 :(得分:0)
您正在传递一个void指针,并且您将指针转换为int或char。您需要取消引用void指针然后强制转换,或者先将其转换为(int *)或(char *)。