2009-11-15 4 views
13

void 포인터와 관련하여 C와 C++의 차이점을 이해하려고합니다.void 포인터 : C와 C++의 차이

int* p = malloc(sizeof(int)); 

malloc 때문에 반환 void*, C++은 C 허용 않는 동안 int*에 할당 할 수 없습니다 : 다음 C에서 컴파일하지만 C++ (모든 컴파일은 GCC/G ++ -ansi -pedantic -Wall으로 수행) 그. 그러나, 여기

: 아무 불평과

void foo(void* vptr) 
{ 
} 

int main() 
{ 
    int* p = (int*) malloc(sizeof(int)); 
    foo(p); 
    return 0; 
} 

모두 C++와 C는 컴파일. 왜?

K & R2 말 : 오브젝트에

상관 포인터 는 정보의 손실없이 void * 유형으로 변환 할 수있다. 결과가 원래 포인터 유형으로 다시 변환 된 인 경우 원래 포인터는 입니다.

이 모든 것이 합쳐져서 void*의 변환이 약 C입니다. C++ 표준은 무엇을 지시합니까?

+0

GMan이 오류의 원인을 올바르게 설명합니다. 즉, C++ 코드를 작성하는 경우 malloc/calloc 대신 free/free를 new/new []와 delete/delete를 사용해야합니다. –

답변

31

C에서 void*에 대한 포인터 변환은 항상 내재적이었습니다. C++에서

T*에서 void*로 전환 암시하지만, 아무것도 void* 다른 캐스트가 필요합니다.

+1

두 번째 문장의 출처를 줄 수 있습니까? C++ 표준으로 작성된 것입니까? – zaharpopov

+6

정말 따옴표가 많지 않습니다. 4.10.2 절에 있습니다.꽤 많이'T *'가'void * '로 변환 될 수 있다고합니다. 반대쪽을 떠나서 캐스트를 사용해야 함을 의미합니다. – GManNickG

+0

@zaharpopov : look reinterpret_cast <> 또는 static_cast <> –

6

C++는 C보다 강력하게 형식 지정됩니다. 특히 값의 다른 해석을 암시하는 변환은 명시 적 변환이 필요합니다. C++의 연산자는 명시 적 형변환없이 힙에 메모리를 할당하는 유형 안전 방법입니다.

0

포인터 유형 변환이 실제로 추가 CPU 명령어의 실행을 필요로하지 않는다는 것을 이해하는 것이 유용합니다. 컴파일 타임 동안 분석되어 개발자의 의도를 이해합니다. void *은 불투명 한 포인터입니다. 그 모든 것은 뾰족한 물체의 유형이 알려지지 않았다고 말합니다. C는 약하게 입력됩니다. 암시 적으로 (void *)와 임의의 것 (T*) 사이를 직접 변환 할 수 있습니다. C++은 강력한 형식입니다. (void *)에서 (T*)으로의 변환은 강하게 유형화 된 언어의 경우에는 적합하지 않습니다. 그러나 C++은 C와의 하위 호환성을 유지해야하므로 이러한 변환을 허용해야했습니다. 따라서 지침 원칙은 암묵적보다 명시 적이다. 따라서 (void*)을 (T*) 특정 포인터로 변환하려면 명시 적으로 코드에 써야합니다. (T*)에서 (void*) 로의 변환은 (void *) 포인터에서 직접 할 수있는 것이 없으므로 명시 적 변환이 필요하지 않습니다. 따라서 (T*)에서 (void*)로 변환하는 것이 훨씬 안전합니다.

+1

포인터 변환에 CPU 명령어가 필요한지 여부는 구현 세부 사항입니다. C 및 C++ 언어에는이 변환이 순전히 개념적 (즉, CPU 명령어가 필요 없음)이되어야합니다. 반대로 두 언어는 서로 다른 포인터 유형에 대해 서로 다른 표현을 허용하도록 특별히 공식화되었습니다. 전형적인 경우에 변환이 실제로 CPU 레벨에서 아무 것도하지 않는다는 것을 "이해"하는 것은 실제로 유용 할 수 있지만, 그 가정에 의존하는 C 또는 C++ 코드를 작성하는 것은 심각한 오류입니다. – AnT

+1

... 그리고 "backward compatible"에 대한 요점을 이해하지 못합니다. C++은'void *'에서 변환하기 위해 명시 적 형 변환이 필요합니다. 그것은 이미 C와 역 호환되지 않습니다. – AnT

+0

C++은 C와 완벽하게 역 호환되지 않습니다. 필요한 곳 ​​어디에서나 쉽게 마이그레이션을 수행 할 수있는 방법을 제공합니다. 약하게 입력 된 것을 강하게 입력 된 것으로 변경하면 자연스럽게 호환성 문제가 발생합니다. C++은 마이그레이션을 쉽게하기 위해 (void 포인터에 명시 적 형 변환을하는 것과 같은) 간단한 방법을 제공하려고합니다. –