1

gcc 6.1.0에서는 컴파일되었지만 gcc에서는 컴파일되지 않은 다음 코드 조각에 대해 "오류 : 배열 유형이있는 표현식에 할당"이라는 오류가 있습니다 4.4.6.va_arg()를 사용하여 argu 구문을 분석하는 중 gcc-6.1.0에서만 오류가 발생했습니다.

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; 

을 그리고 당신은 시도 :

+0

나는 strcpy (ad, va_arg (ap, mac_t));를 시도했다. 컴파일러 오류가 발생하지 않습니다. 그러나 그것은 목적을 달성하지 못합니다. 인수가 배열 광고에 복사되지 않습니다. 광고 내용을 인쇄 할 때 잘못된 데이터가 표시됩니다. –

+1

배열은 함수에 전달 될 때 포인터 유형으로 감소합니다. gcc 6.1.0에서는 올바르게 처리되지만 배열에 할당 할 수는 없습니다. – jxh

+0

@jxh 정확합니다. 포인터에 대해 strcpy()가 작동하지 않습니다. gcc 6.1.0에서 인수를 구문 분석하는 다른 방법은 없습니까? –

답변

1

는 당신이이 같은 인수를 통과 한

ad = va_arg(ap, mac_t); 

가 :

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

이 오류가 발생합니다. 배열에 할당 할 수 없습니다. 또한 "AABBCC"은 NUL 종료 문자열 리터럴 때문에 char의 배열 [7]입니다. 그러나 그것은 중요하지 않습니다. 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 첫 번째 인수로 char *을 기대하고 있기 때문에

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

우리는 ad 강요.

+0

예. 이 솔루션은 효과가있었습니다. –