使用va_arg()解析参数时仅在gcc-6.1.0中发现错误

时间:2017-01-11 09:56:01

标签: c gcc compiler-errors compiler-warnings variadic-functions

对于我在gcc 6.1.0中编译但未在gcc 4.4.6中编写的下一段代码,我发现错误“错误:赋值给表达式与数组类型”。

void foo(char *fmt, ...)
{
    va_list ap;
    int d;
    char *c, *s;
    typedef unsigned char mac_t[6];

    mac_t ad;   
    va_start(ap, fmt);
    while (*fmt)
    switch (*fmt++) {
    case 's':  
        s = va_arg(ap, char *);
        printf("string %s\n", s);
     break;
    case 'd':              /* int */
        d = va_arg(ap, int);
        printf("int %d\n", d);
    break;
    case 'c':              /* char */
        ad = va_arg(ap, mac_t);  //**** error here only on gcc 6.1.0 compiler 
        printf("With unsigned char: char %c.%c.%c.%c.%c.%c\n", ad[0],ad[1],ad[2],ad[3],ad[4],ad[5]);                                              
    }
    va_end(ap);
}
int main()
{
    foo("%c", "AABBCC");
}    

如何解决此错误?在gcc 4.4.6中,编译顺利通过。由于某些原因,我只需要使用gcc 6.1.0编译器。

1 个答案:

答案 0 :(得分:1)

你有:

typedef unsigned char mac_t[6];
mac_t ad;   

然后你尝试:

ad = va_arg(ap, mac_t);

什么时候,你已经通过了这样的论证:

foo("%c", "AABBCC");

这是一个错误。您无法分配给数组。此外,"AABBCC"是char的数组[7],因为NUL终止了字符串文字。但是,这没关系。 foo()收到char *,因为数组类型会衰减到包含其第一个元素地址的指针。

如果将-std=c99传递给GCC,您应该能够看到错误。显然,这可以进行更严格的检查。

gcc -std=c99 -W -Wall -O c.c
c.c: In function ‘foo’:
c.c:25:12: error: incompatible types when assigning to type ‘mac_t’ from type ‘unsigned char *’
         ad = va_arg(ap, mac_t);  // error here only on gcc 6.1.0 compiler
            ^

要解决此问题,请告诉va_arg您正在解析指针。如果您必须复制内容,请使用strncpy

strncpy((void *)ad, va_arg(ap, char *), sizeof(ad));

我们强制ad,因为strncpy期望char *作为第一个参数。