문제는 const
입니다. 함수는 const array_t *
(const array_t에 대한 포인터)을 반환하지만 반환되는 표현식 &_my_array
은 array_t *
이며 두 유형은 호환되지 않습니다.
typedef uint8_t array_t[8];
static array_t _my_array;
static array_t * foo(void) {
return &_my_array;
}
편집 :
간단한 수정 반환 형식에서 const
을 드롭하는 것입니다
내가 컴파일러의 버그를 제안 주저 해요,하지만 난 함께 왔어요 내가 생각하는 테스트 프로그램은 gcc의 버그 또는 C 표준의 매우 모호한 부분을 나타냅니다.
typedef int this_type;
typedef int that_type[8];
static this_type this;
static that_type that;
static const this_type *this_func(void) {
return &this;
}
static const that_type *that_func(void) {
return &that;
}
나는 이것을 컴파일
gcc -c -std=c99 -pedantic-errors c.c
(GCC 4.5.2), 내가 얻을 :
c.c: In function ‘that_func’:
c.c:12:5: error: return from incompatible pointer type
이 왜 const that_type*
에 that_type*
에서 암시 적 변환에 대해 불평 않지만, this_type*
에서하지에 대한 변환 const this_type*
. that_type
이후
가 타입 정의 , 그것은 배열 형 별칭, 그리고 that_type*
배열 (되지 배열의 요소에 대한 포인터)에 대한 포인터; 내가 말할 수있는 한 배열에서 포인터로의 변환은 없다. 나는 그렇지 않다 은 this_type
이 정수형이고 that_type
이 배열 형식 인 것이 차이를 만들어야한다는 것을 생각한다.
다른 데이터 요소 : Solaris 9의 경우 cc -c -Xc c.c
은 불만하지 않습니다.
foo 포인터를 const foo에 대한 포인터로 변환하는 것이 안전해야합니다. const-correctness를 위반할 기회는 없습니다.
내가 옳다 경우, 해당 코드가 유효 GCC의 경고는 잘못된 것입니다, 당신은 함수 정의에 const
놓아 그 중 하나를 해결할 수 있습니다 (이 const array_t*
보다는 array_t*
를 반환 할, 또는로 return 문에 캐스트를 추가합니다.
return (const array_t*)&_my_array;
내가 잘못하면 곧 누군가를 가리킬 것으로 예상됩니다.
(.. 식별자가 다소 고의적으로 this
하는 C++ 키워드의 내 사용, 이것은 내가 C++이 지역에서 약간 다른 규칙이 있음을 이해할 C의 질문입니다.)
EDIT2 : I 방금 gcc bug report을 제출했습니다.
EDIT3 : 조셉 S. 마이어스 내 버그 보고서에 응답 :
이것은 버그가 아닙니다. 암시 적으로 "int에 대한 포인터"는 "const int에 대한 포인터"로 변환 될 수 있지만 "int 배열"에 대한 포인터 " "(6.5.16.1 참조) 및 "const that_type *" "const int의 배열에 대한 포인터"입니다 (" const int 배열"에 대한 포인터는 이러한 형식이 아니며, 이러한 변환은 변환의 허용 된 대상입니다 (6.7.3 # 8 참조).
이것은 사용자의 문제와 관련이 없지만 식별자 '_my_array'의 사용은 좋지 않습니다. C99 7.1.3 : "밑줄로 시작하는 모든 식별자는 항상 일반 및 태그 이름 공간에서 파일 범위가있는 식별자로 사용하도록 예약되어 있습니다." –
은 static array_t _my_array 파일 범위가 아닙니다. –
네, 그게 문제입니다. 이러한 식별자는 구현 *에 예약되어 있습니다. 자신을 사용할 수 없습니다. 동일한 섹션의 뒷부분에서 : "프로그램이 예약 된 컨텍스트에서 식별자를 선언하거나 정의하면 [...] 동작이 정의되지 않았습니다." 구현 (컴파일러 또는 미리 정의 된 헤더)은 "_my_array"라는 자체 파일 범위 엔티티를 선언 할 수 있습니다. 최신 C99 초안은 [here] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)입니다. –