void * a = & a는 어떻게 합법적입니까?


88

다음 C ++ 코드를 고려하십시오.

void* a = &a;

컴파일러가 선언되지 않은 식별자 사용에 대해 불평하지 않는 이유는 무엇입니까?

또한 컴파일러는 변수 a를 무엇으로 간주 합니까? void 객체에 대한 void*포인터입니까 아니면 포인터에 대한 포인터입니까?




15
왜 이것을하고 싶은지 언급해야합니다-스택의 맨 위에 포인터를 가져 오려면 (모든 종류의 작업을 할 수 있습니다).
OrangeDog

답변:


95

C ++에서 변수 선언의 범위는 매우 놀랍습니다.

void* a =               &a;
         ^~~~~~~~~~~~~~~~~
          a declared as `void*` from here on

따라서, &a이다 void**그러나 어떤 포인터 형식 이후에 암시 적으로 변환입니다 void*...


이것에 유용한 객체를 어떻게 할당합니까?
user2681063

22
@ user2681063 a = &userfulObject?
Nikos C.

4
@MarkGarcia : void *a = a;로컬로 선언하면 UB가됩니다. 그렇지 않으면 네임 스페이스 범위에서 괜찮습니다.
Nawaz

1
@TheodorosChatzigiannakis : 그렇습니다.
Matthieu M.

1
여기에서 사양 인용이 정말 좋을 것입니다.
Benjamin Gruenbaum 2013-08-21

30

다음과 같습니다.

void* a;
a = &a;

따라서 a선언되었습니다. 그래서 aa쓰여진 주소를 얻 습니다 a. 그래서 그것은 void 포인터에 대한 포인터입니다. (아직 개체를 정의하지 않았습니다.)


9
기술적으로는 하나의 개체를 정의했습니다. a그 자체가 객체입니다. (모든 객체가 C ++에서 사용자 정의 유형을 가지는 것은 아닙니다)
MSalters

1
@MSalters 당신이 말하는이 '객체'는 무엇입니까? : D
Gusdor 2013-08-14

3
@Gusdor 우리는 사건 지평선의 공백 너머에있는 것만 추측 할 수 있습니다.
Cole Johnson

그들은 그러나 "효과가"이 경우 동일 다르게 불린다
Stasik

일반적으로 동일하지는 않지만 시나리오에서는 동일합니다.
궤도의 가벼운 경주

7

에서 void* a, a아닌 포인터로 선언 void유형하지만 "모든"유형 (특별한 경우)에. a물론 선언되는 다른 변수와 마찬가지로 주소 (메모리의 위치)가에 할당됩니다 .

그 후, 방금 선언 된 &a변수를 초기화하기 위해 표현식 이 평가됩니다 ( a이는 관련이 없습니다). 의 유형 &a은 "모든 유형에 대한 포인터에 대한 포인터"이며, "모든 유형에 대한 포인터"의 특수한 경우이며의 유형과 완전히 호환됩니다 a. Ergo, 컴파일러 메시지가 없습니다.

결과 : void*강력한 유형 검사를 원하는 경우 사용하지 마십시오 . 무엇이든 변환 할 수 있습니다. void*그 자체를 제외하고는 반대 방향으로 반대입니다 (유형이 자신과 호환되지 않는 것은 불필요한 예외입니다).

또한 AFAIR는 실제로 C에서 비롯됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.