1

Я нахожу ошибку, говоря «ошибка: назначение выражению с типом массива» для моей следующей части кода, скомпилированной в gcc 6.1.0, но не в gcc 4.4.6.Ошибка обнаружена только в gcc-6.1.0 при анализе аргументов с использованием va_arg()

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.

+0

Я попробовал strcpy (ad, va_arg (ap, mac_t)) ;. Это не дает мне никакой ошибки компилятора. Но это не служит цели. Я имею в виду, что аргументы не копируются в объявление массива. При печати содержимого объявления я вижу недопустимые данные. –

+1

Массивы распадаются на тип указателя при передаче функции. gcc 6.1.0 исправляет это, вы не можете назначить массив. – jxh

+0

@jxh Точно. strcpy() не работает с указателями. Любой другой способ проанализировать аргументы в gcc 6.1.0? –

ответ

1

У вас есть:

typedef unsigned char mac_t[6]; 
mac_t ad; 

И затем вы пытаетесь:

ad = va_arg(ap, mac_t); 

Когда вы прошли аргумент так:

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

Это ошибка. Вы не можете назначить массив. Кроме того, "AABBCC" является массивом [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 * в качестве первого аргумента.

+0

Да. Это решение сработало. –