字符是否作为整数传递给被调用的函数?

时间:2015-02-18 23:12:50

标签: c gcc integer character variadic-functions

我写了下面的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}}?

感谢。

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 即可。如果表示被调用函数的表达式具有包含原型的类型,   参数被隐式转换,就像通过赋值一样,转换为类型   相应的参数,将每个参数的类型作为不合格的版本   其声明的类型。函数原型声明符中的省略号表示法导致   参数类型转换在最后声明的参数后停止。默认参数   促销是在尾随参数上进行的。