2014-09-22 3 views
3

3.9/6 N3797 :알 수없는 크기의 배열에 대한 포인터가 불완전합니까?

가 [...]

또는 typedef를 선언하여 정의 타입의 알려지지 않은 크기의 어레이에 대한 포인터의 타입은 알려지지 않은 크기의 배열 될 , 을 완료 할 수 없습니다.

알 수없는 크기의 배열에 대한 포인터처럼 들리는 것은 불완전한 유형입니다. 그렇다면 알 수없는 크기의 배열에 대한 포인터 객체를 정의 할 수 없습니다. 그러나 미지의 경계를 정의 할 수 있기 때문에 사실이 아닙니다.

#include <iostream> 

using std::cout; 
using std::endl; 

int (*a)[] = (int(*)[])0x4243afff; 

int main() 
{ 

} 

잘 컴파일됩니다.

DEMO

우리는 불완전한 형태 인 경우에 그것을 할 could't. 사실 : 3.9/5 :

객체는 3./5 다음과 같이 표준 이전에 불완전한 유형을 정의

불완전한 유형을 정의 할 수 없다 :

클래스가 열거 형인 경우 특정 컨텍스트 (7.2) 또는 알 수없는 크기의 배열 또는 불완전한 요소 유형의 배열이 불완전하게 정의 된 개체 유형입니다. 불완전하게 정의 된 객체 유형 및 void 유형이 불완전한 유형 (3.9.1)입니다.

이는 불완전한 유형의 포인터가 완료되었음을 의미합니다. 모순?

그래서 내가 내 추론에서 잘못 되었나요?

+2

왜 당신은 불완전한 유형의 포인터를 가질 수 없다고 생각하십니까? – BadZen

+0

은 "typedef 구조체 목록 {void * value; struct list * nxt; } 목록 "? – BadZen

+0

그건 배열이 아니에요 그냥 메모리 주소예요 –

답변

6

나는이 표현에 결함이 있다고 생각합니다. 귀하의 코드에서 :

int (*a)[]; 

a 유형이 실제로 완료되었습니다. *a 유형이 불완전합니다. 견적의 목적은 나중에 프로그램에서 *a이 완전한 유형의 표현이 될 방법이 없다고 말하는 것이 었습니다 (dyp이 의견에서 말한 것처럼).

배경 : 일부 불완전한 유형은 나중에 예를 들어 완료 할 수 있습니다. cdhowie 및 dyp에서 제안한대로 :

extern int a[]; 
int b = sizeof a; // error 
int a[10]; 
int c = sizeof a; // OK 

int (*a)[];은 나중에 완료 할 수 없습니다. sizeof *a은 항상 오류입니다.

+1

"알 수없는 크기의 배열에 대한 포인터 또는 알 수없는 크기의 배열이 될 typedef 선언이있는 경우 배열 유형을 완료 할 수 없습니다"와 같은 표현은 명확성을 향상시킬 수 있습니다. (아마 그것은 어쩌면 여전히 약간의 말씨를 사용할 수 있습니다.) – cdhowie

+0

독자에게 예제를 제공하기 위해이 컨텍스트에서 "완료 할 수 없음"이란 의미는 나중에 배열의 크기를 제공 할 수 없다는 것입니다. 예를 들어'int a []; 선언이 주어지면이 타입은 불완전하지만 * 완료 될 수 있습니다 * - 나중에 int a [10];을 지정하여 타입을 완성 할 수 있습니다. 그러나 int (* a) []; 선언문을 받으면 나중에 * * int (* a) [10];의 형식을 완료 할 수 없으므로 오류가됩니다. '* a'는 불완전한 타입 인 int []를 갖기 위해 영원히 운명입니다. – cdhowie

+2

@cdhowie 나는 'extern int a [];'가 법적인 선언이기 때문에 더 좋을 것이라고 생각한다. – dyp

0

C++ 문과 마찬가지로 문구에서 영문 문장은 으로 해석되어야합니다. 인용 된 문장의 문맥은 그 의미를 완벽하게 밝혀줍니다. 단락은 (§3.9 [기본.타입]/P6, 당신이 인용 한 문장) 굵게 :

클래스 유형 (예 : "class X") 번역 단위에서 한 지점에서 불완전하고에 나중에 완료 할 수있다; "class X"유형은 두 지점 모두에서 동일한 유형 인 입니다. 배열 객체의 선언 된 유형은 이 불완전한 클래스 유형의 배열이므로 불완전 할 수 있습니다. 나중에 번역 단위에서 클래스 유형이 완료되면 배열 유형이 완료됩니다. 이 두 점의 배열 유형은 유형과 동일합니다. 배열 객체의 선언 된 유형은 알 수없는 크기 의 배열 일 수 있으므로 단위의 번역에서 한 지점에서 불완전하며 이후에 완료됩니다. 이들 두 점에서 어레이 유형 ("미지의 배열 T의 결합"및 "N T 배열")는 다른 유형 이다. 알 크기의 어레이에 대한 포인터의 유형 또는 typedef 선언에 의해 정의 된 형식 알려지지 않은 크기의 배열로, 완료 될 수 없다.

맥락에서 읽기, 분명 "T의 경계 알의 배열에 대한 포인터가"객체가 선언하는 방식으로 "N T의 배열에 대한 포인터"에 "완료"할 수 없다는 것 "T"의 알려지지 않은 배열로 나중에 정의 할 수 있습니다 "T"

+0

* "인용문의 문맥은 그 의미가 완벽하게 분명해진다"* OP의 이전 질문에서 추측 해 보면, 나는 OP가 그 문맥을 알고 있지만 그 문장을 이해하지 못했다고 생각할 것이다. 또한이 인용문은 포인터 유형 자체가 불완전한 지 여부를 알려주지 않습니다. – dyp

+0

@dyp 3.9/p5는 질문에 인용되어 있습니다. –

+0

"완료된"의미가 무엇인지 이해하는 것은 분명히 중요한 문제입니다. 내가 뭔가를 완성한다면, 그것은 불완전하다. 그러나 그런 종류의 불완전 성은 3.9/5에 정의 된 것과 동일하지 않다. 나는 이것이 조금 혼란 스럽다고 생각한다. 나는 3.9/6 *의 맥락이 분명히이 차이를 지적한다고 생각하지 않는다. – dyp

관련 문제