불완전한 유형에 대한 포인터가 불완전 할 수 있습니까?


9

int (*)[]불완전한 유형을 수?

C 2018 6.2.5 1의 말 :

변환 단위 내의 다양한 지점에서, 객체 유형이 불완전 하거나 ( 해당 유형의 객체 크기를 결정 하기에 충분한 정보가 없음) 완료 (충분한 정보가 있음) 될 수 있습니다.

따라서 유형의 크기를 알면 유형이 완전한 것 같습니다. 6.2.6.1 28은 특정 유형의 포인터가 동일한 크기 (포인터 void및 문자, 호환 가능한 유형, 구조체 및 공용체 에 대한 포인터)를 가져야 하지만 다른 유형에 대한 포인터는 다를 수 있음을 지정합니다.

모든 포인터 또는의 배열에 대한 모든 포인터가 int동일한 크기를 갖는 C 구현에서는 크기 int (*)[]가 알려져 있으므로 완료됩니다. 예를 들어, 큰 배열에 다른 포인터를 사용하는 구현에서는 크기를 알 수 없으므로 불완전합니다.

으로 MM 지적 , 구조는 6.7.2.1이 포인터의 한 크기의 구현을 수용해야합니다 제안 3에 제약 당, 최종 유연한 배열 구성원을 제외시켰다 불완전한 유형의 구성원을 포함 할 수 없습니다 struct { int (*p)[]; }구현이 다른이 그 동안 이러한 배열의 크기는 제약 조건 위반을 진단해야합니다. (이것은 그러한 선언이 C를 엄격히 준수하는 것이 아님을 의미합니다.)


6.2.5 (p22) 도움이 필요하십니까? (또는 나중에 선언하여 불완전한 유형을 완성 할 수 있도록 혼동을 더 추가합니까?)
David C. Rankin

@ DavidC.Rankin 6.2.5 / 20에서는 포인터가 항상 완전한 유형이라고합니다
Christophe

@LanguageLawyer : 어떻게 관련이 있습니까? 문제는“Y가 아닌 X가 있습니까?”가 아니라“Y 인 X가 있습니까?”입니다.
Eric Postpischil

@LanguageLawyer : void *완료 되었다는 사실 은 불완전한 유형에 대한 포인터가 완료 될 수 있음을 나타냅니다. 불완전한 유형에 대한 포인터가 불완전 할 수 있는지 여부는 표시하지 않습니다. “포유 동물이 코끼리가 될 수 있는가?”라고 물으면“사자가 포유 동물이다”는 것이 포유 동물이 코끼리가 될 수 없다는 것을 의미하지는 않습니다. 이 질문은 불완전한 유형에 대한 포인터의 X 세트가 불완전한 요소를 포함하고 있는지 묻습니다. 불완전한 유형에 대한 포인터의 X 세트가 완료된 요소를 포함하고 있음을 보여주는 것은 관련이 없습니다.
Eric Postpischil

@EricPostpischil 죄송합니다. 나는 "불완전한 타입에 대한 포인터가 될 수있는 제목을 오해 한 완전한 ?"
언어 변호사

답변:


3

알 수없는 크기의 배열이 불완전합니다.

알 수없는 크기의 배열 유형이 불완전한 유형입니다. 해당 유형의 식별자에 대해서는 이후 선언에서 내부 또는 외부 연결로 크기를 지정하여 완료됩니다.

그러나 유형 int (*)[]이 불완전하지 않습니다 int. 크기가 알 수없는 배열의 포인터입니다 .
그리고 포인터는 잘 알려진 크기를 가지고 있습니다 :

printf ("Size %d\n", sizeof(int (*)[]));

6.2.5 / 23 : 유형이 불완전하지 않고 가변 길이 배열 유형이 아닌 경우 유형의 상수 크기가 알려져 있습니다.

또한 배열 의미론 덕분에이를 역 참조 할 수도 있습니다.

typedef int (*T)[];
...
int a[10];
for (int i=0; i<10; i++) a[i]=i;
T p=a;
for (int i=0; i<10; i++) printf ("%d ",(*p)[i]);
printf ("\n");

편집하다

또한 포인터는 항상 완전한 유형입니다. 6.2.5 / 20에서 흰색으로 검정색으로 표시됩니다.

포인터 유형은 함수 유형 또는 참조 된 유형이라고하는 객체 유형에서 파생 될 수 있습니다. 포인터 유형은 값이 참조 된 유형의 엔티티에 대한 참조를 제공하는 오브젝트를 설명합니다. 참조 된 유형 T에서 파생 된 포인터 유형을 때때로 ''포인터에 대한 포인터 ''라고합니다. 참조 된 유형으로부터 포인터 유형을 구성하는 것을``포인터 유형 도출 ''이라고합니다. 포인터 유형은 완전한 객체 유형입니다.


나는 당신이 그것을 끓여서 gcc가 동의한다고 생각합니다. 불완전한 배열에 대한 포인터가있는 구조체 는 토론을 요구하는 원래 질문과 유사합니다.
David C. Rankin

마지막 단락 만 관련이 있습니다. 이 예제 printf는 질문에서 언급 한 것처럼 불완전한 배열에 대한 포인터가 실행 된 구현에서 완료되었음을 보여줍니다. 6.2.5 23도 관련이 없습니다. 크기가 알려지면 일정하고 크기가 일정하다는 것을 알려줍니다. 완성 된 크기는 크기가 알려져 있음을 이미 알고 있습니다.
에릭 Postpischil

6.2.5 20가 흥미 롭습니다. 필자는이 결과를 의도하지 않았지만 불완전한 유형이 동일한 유형을 완료하는 모든 포인터의 크기가 같아야 함을 의미합니다. 예를 들어, 배열의 모든 포인터 int는 서로 같은 크기를 struct가져야 하며 특정 배열의 모든 포인터는 서로 struct같은 크기를 가져야합니다. 서로.
에릭 Postpischil

1
@EricPostpischil은 아마도 "유사하거나 호환되지 않는 호환되는 유형의 버전에 대한 포인터는 동일한 표현 및 정렬 요구 사항을 가져야합니다."라는 텍스트 일 ​​수 있습니다. 그 말을 해석해야한다 T(*)[]와 같은 크기가 있어야합니다 T(*)[5]그들은 호환 타입이기 때문에, 우리는 규정을 추가하거나 제거 할 수 있습니다
MM

호환 가능한 유형이 다른 크기를 갖도록 허용하면 많은 문제가 발생할 수 있습니다. 아마도 표준에서 명시 적으로 배제하지 않는 것은 아마도 결함 일 것입니다
MM
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.