“int * ptr = int ()”값 초기화가 어떻게 불법이 아닌가?


86

다음 코드 ( 여기에서 가져옴 ) :

int* ptr = int();

Visual C ++에서 컴파일하고 포인터를 값 초기화합니다.

어떻게 가능합니까? 내 말 int()은 유형의 객체를 산출 하고 포인터에을 int할당 할 수 없음을 의미합니다 int.

위의 코드가 불법이 아닌 이유는 무엇입니까?


대답은 아니지만 좋은 질문입니다! 그런 건 본 적이 없어요.
Josh

6
프리미티브 C에서 '생성자'을 가지고 있기 때문에 ++, int()값 구성 값 산출 int및 기본값 (나는 C ++ 03 지정된 것은 생각입니다) int입니다 0. 이것은 다음과 동일합니다.int *ptr = 0;
wkl

7
@EmanuelEy : 아니요, 포인터가 실제로 구현되는 방식에 관계없이 0 값 정수 상수를 널 포인터 상수로 사용할 수 있습니다.
Mike Seymour

1
@MooingDuck : NULL0이 아닌 값이 될 수 있다고 말하지 않았습니다 . 나는 그것이 0 값 정수 상수 (포함 int()) 일 수 있다고 말했습니다 .
Mike Seymour 2011

5
@DanielPryden 그것은 내가 이전에 알지 못했던 "객체"라는 단어의 사용입니다.
푹신한

답변:


110

int()값이 0 인 상수 표현식이므로 널 포인터 상수를 생성하는 유효한 방법입니다. 궁극적으로 약간 다른 표현 일뿐입니다.int *ptr = NULL;


3
+1, 상수 표현 비트는 중요하며 상위 2 개 찬성 답변에서 누락되었습니다.
David Rodríguez-dribeas 2011

이것이 C ++ 0x로 사라지나요?
Neil G

@NeilG : C ++ 11에서도 동일하게 유지되지만 이제는 새 코드 nullptr대신 0또는 NULL새 코드에서 사용할 수있는 .
Jerry Coffin 2011

2
@Nils : 코드 명확성 및 코드를 통한 의도 선언. 물론, C ++ 11에서는 추가 컴파일 시간 검사의 이점을 혼합에 던지기 때문에 이제 nullptr을 사용하고 싶습니다.
Jamin Gray 2013

3
@Nils는 분명히 0null 포인터 상수 또는 숫자 0을 의미 할 수있는 반면 nullptrnull 포인터 상수는 분명하기 때문입니다. 또한 Jamin이 말했듯이 "추가 컴파일 시간 검사"도 있습니다. 입력하기 전에 생각하십시오.
Miles Rout

35

때문에 int()수율 0로 교체이다 NULL. NULL자체로 정의 0C 년대와는 달리 NULL입니다 (void *) 0.

이것은 오류입니다.

int* ptr = int(5);

그리고 이것은 여전히 ​​작동합니다.

int* ptr = int(0);

0특수 상수 값이므로 포인터 값으로 처리 할 수 ​​있습니다. 수율하는 정수 표현 0등이뿐만 1 - 1아니라 널 포인터 상수로 사용할 수 있습니다.


1
또한 C의 NULL도 반드시 그런 것은 아닙니다 (void *)0. 이는 단순히 "값이 0 인 정수 상수 표현식 또는 void * 유형으로 캐스팅 된 표현식"으로 정의 된 구현입니다.
Jerry Coffin 2011

@JerryCoffin 저는 다음 NULL과 같이 정의 된 C 컴파일러를 사용한 적이 없습니다 (void*)0. 항상 0(또는 어쩌면 0L). (하지만 C90이 (void*)0C에서 합법화되었을 때 이미 C ++를 사용하고있었습니다.)
James Kanze

1
@JamesKanze : 우분투 11.04와 우리의 리눅스 #if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)버전 에서 libio.h는 다음을 포함합니다 : 우분투에있는 gcc의 현재 버전은 4.5이고 우리 시스템에서는 4.0입니다.
David Rodríguez-dribeas

5
" 0은 특수 리터럴입니다"-상수 표현식이고 특수 값 0을 갖기 때문 (1-1)입니다. 똑같이 특별하고 널 포인터 상수이기도합니다 int(). 0리터럴 이라는 사실 만으로도 충분하지만 상수 표현이되기위한 필수 조건은 아닙니다. 과 같은 strlen("")것은 특별한 값을 가지고 있지만 0상수 표현식이 아니므로 널 포인터 상수가 아닙니다.
Steve Jessop 2011

@SteveJessop : 수정에 대해 동의합니다. 실제로 00리터럴이 아닌 상수 값에 관한 것 입니다.
Blagovest Buyukliev 2011

18

표현식 int()은 기본값으로 초기화 된 상수 정수로 평가되며 값은 0입니다.이 값은 특별합니다. NULL 상태에 대한 포인터를 초기화하는 데 사용됩니다.


2
이것은 Jerry의 대답에 존재하는 매우 중요한 세부 사항이 누락되었습니다. 표현식이 값 0을 산출하는 것으로는 충분하지 않지만 상수 표현식 이어야합니다 . 반대 예의 경우 with int f() { return 0; }, 표현식 f()은 값 0을 산출하지만 포인터를 초기화하는 데 사용할 수 없습니다.
David Rodríguez-dribeas 2011

@ DavidRodríguez-dribeas, 가능한 가장 간단한 용어로 답을 제시하기 위해 서두르면서 그 부분을 생략했습니다. 지금 받아 들여지기를 바랍니다.
Mark Ransom 2011

13

n3290 (C ++ 03은 유사한 텍스트 사용)에서 4.10 포인터 변환 [conv.ptr] 단락 1 (강조는 내 것임) :

1 널 포인터 상수는 0으로 평가되는 정수 유형의 정수 상수 표현식 (5.19) prvalue 또는 std :: nullptr_t 유형의 prvalue입니다. 널 포인터 상수는 포인터 유형으로 변환 될 수 있습니다. 결과는 해당 유형의 널 포인터 값이며 오브젝트 포인터 또는 함수 포인터 유형의 다른 모든 값과 구별 할 수 있습니다. 이러한 변환을 널 포인터 변환이라고합니다. [...]

int()0으로 평가되는 정수 유형의 정수 상수 표현식 prvalue이므로 포인터 유형을 초기화하는 데 사용할 수 있습니다. 보시다시피, 0는 특수한 경우에만 적분식이 아닙니다.


4

int는 객체가 아닙니다.

나는 여기서 무슨 일이 일어나고 있는지 당신이 int *가 int ()에 의해 결정된 메모리 주소를 가리 키도록 지시하고 있다고 믿습니다.

따라서 int ()가 0을 생성하면 int *는 메모리 주소 0을 가리 킵니다.


1
int()가장 확실한 것은 객체입니다.
궤도의 가벼운 경주

@Tomalak : 나는 그렇게 생각하지 않는다. 클래스가 아닌 유형의 일시적이며 C ++ 표준에 관한 한 객체 가 아니라고 말하는 것이 옳다고 생각 합니다. 그러나 "임시 객체"에 대한 섹션은 클래스 유형의 임시에 대해서만 신중하게 설명하기 시작하지만 나중에는 바인딩 참조에 대해 설명하고 물론 참조를에 바인딩 할 수 있습니다 int(). int i;의문의 여지없이 정의 i는 객체입니다.
Steve Jessop 2011

@Steve : "객체"는 C ++의 저장소 영역이고 임시 저장소에는 실제로 저장소가 없다는 점에서이 문제에 대한 논쟁 만 기대할 수 있습니다. 그렇죠? 1.8 / 1은 임시를 명시 적으로 나열하지 않지만 포함하려는 의도가있는 것처럼 느껴집니다.
궤도의 가벼운 경주

1
@Tomalak : 예, 실제로 비 클래스 유형의 임시 파일은 참조하지 않는 한 스토리지가 필요하지 않습니다. 그래도 신경 쓰지 마세요.별로 중요하지 않습니다. "well int is not an object"라는 문장은 객체가 아니라 int유형 이기 때문에 참 입니다. int()객체를 생성 하든 rvalue 만 생성 하든 다른 사람이 말한 것에 영향을 미치지 않습니다.
Steve Jessop 2011

@Steve : 그 정도는 논란의 여지가 없습니다. :)
궤도의 Lightness Races
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.