我写了下面的C程序,用可变数量的参数调用函数。
#include<stdio.h>
#include<stdarg.h>
void display(int, int, ...);
int main()
{
display(1,5,1,2,3,4,5);
display(2,3,'A','B','C');
printf("\n");
return 0;
}
void display(int type, int tot_num, ...)
{
int i, j;
char c;
va_list ptr;
va_start (ptr, tot_num);
switch(type)
{
case 1:
for (j=0; j<tot_num; j++)
{
i = va_arg (ptr, int);
printf("%d ",i);
}
break;
case 2:
for (j=0; j<tot_num; j++)
{
c = va_arg(ptr, char);
printf("%c ",c);
}
}
}
然而,当我编译程序时,我得到了来自gcc的警告。
-bash-4.1$ gcc varArg3.c
varArg3.c: In function âdisplayâ:
varArg3.c:41: warning: âcharâ is promoted to âintâ when passed through â...â
varArg3.c:41: note: (so you should pass âintâ not âcharâ to âva_argâ)
varArg3.c:41: note: if this code is reached, the program will abort
-bash-4.1$
第41行是c = va_arg(ptr, char);
当我为va_arg阅读man 3页时,提到如下:
如果没有下一个参数,或者type与实际的下一个参数的类型不兼容(根据默认参数提升而提升),则会发生随机错误。
当我读到这篇文章时,我认为c = va_arg(ptr, char);
是正确的,因为变量参数列表中的数据是字符。但是gcc上面的警告表明传递的变量参数不是真正的字符而是整数。
根据gcc的建议,我将其更改为c = va_arg(ptr, int);
,现在我没有收到任何警告。我运行程序时也得到预期的输出。
那么,diplay()
中的字符(在main()
中的display()
的第二次调用中)是否作为整数传递给{{1}}?
感谢。
答案 0 :(得分:2)
是'A'
的类型是int
,请尝试此
printf("typeof('A') == typeof(int) -> %s\n",
(sizeof('A') == sizeof(int)) ? "YES" : "NO");
并亲自检查。
修改:
根据Jonathan Leffler的评论,即使您这样做,也会发出警告
char a = 'A';
然后通过了a
,因为它无论如何会被提升为int
,所以这意味着
int arg = va_arg(ptr, int);
总是正确的,评论中提到的标准部分说明如下
<强>§6.5.2.2强>
<强> 7 即可。如果表示被调用函数的表达式具有包含原型的类型, 参数被隐式转换,就像通过赋值一样,转换为类型 相应的参数,将每个参数的类型作为不合格的版本 其声明的类型。函数原型声明符中的省略号表示法导致 参数类型转换在最后声明的参数后停止。默认参数 促销是在尾随参数上进行的。