![](/img/trans.png)
[英][C]Can I call va_arg with a larger type than the argument, then cast the value?
[英]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
传递, char
, unsigned char
, signed char
, short
, unsigned short
根据需要进行升级到int
或unsigned (int)
。 因此,您永远不能使用va_arg
直接提取char
; 您只能指定推广类型。 你必须写:
char c = (char) va_arg(argptr, int);
float f = (float) va_arg(argptr, double);
这一次,演员是由于作业而发生的; 说它发生在演员表上并不是绝对必要的,但没有坏处(虽然我可能不会在我自己的代码中编写演员表)。
问题是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)
。
数组args
是一个void *
数组。 您为它分配纯整数,这是您得到错误的原因。
您正在传递一个void指针,并且您将指针转换为int或char。 您需要取消引用void指针然后进行转换,或者首先将其转换为(int *)或(char *)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.