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

标签 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 编译器。

最佳答案

你有:

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 * 作为第一个参数。

关于c - 使用 va_arg() 解析参数时仅在 gcc-6.1.0 中发现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41587638/

相关文章:

用 sizeof 初始化常量数组

c++ - musl 的 GCC 包装器与 musl 的交叉编译器有何不同?

c++ - C/GCC 中可重复的全局声明

java - 简单java归档代码中的FileNotFound异常错误

c ) make error& link problem : i386:x86-64 architecture of input file, 与 i386 输出不兼容

c - 使用 scanf() 进行输入验证

c - 如何定义和声明库代码使用的全局变量?

java - Java编译/包/ namespace 错误

c# - 什么是 C snprintf() 的 C# 模拟?

linux - gcc:在 32 位平台上编译 64 位二进制文​​件