Programing

NULL 포인터가 C와 C ++에서 다르게 정의되는 이유는 무엇입니까?

lottogame 2020. 10. 30. 07:40
반응형

NULL 포인터가 C와 C ++에서 다르게 정의되는 이유는 무엇입니까?


C에서는 NULL로 정의 (void *)0되지만 C ++에서는 0. 왜 그래야만하지? CI에서 NULL타입 캐스트가 아닌 경우 (void *)컴파일러가 경고를 생성하거나 생성 하지 않을 수 있음을 이해할 수 있습니다 . 이 외에 이유가 있나요?


C ++ 03에서 널 포인터는 ISO 사양 (§4.10 / 1)에서 다음과 같이 정의되었습니다.

널 포인터 상수는 0으로 평가되는 정수 유형의 정수 상수 표현식 (5.19) rvalue입니다.

이것이 C ++에서 작성할 수있는 이유입니다.

int* ptr = 0;

C에서이 규칙은 비슷하지만 약간 다릅니다 (§6.3.2.3 / 3).

값이 0 인 정수 상수 표현식 또는 type으로 캐스트 된 표현식을 void *널 포인터 상수라고합니다 .55) 널 포인터 상수가 포인터 유형으로 변환되면 결과 포인터 인 널 포인터가 보장됩니다. 객체 나 함수에 대한 포인터와 같지 않음을 비교합니다.

결과적으로

int* ptr = 0;

int* ptr = (void *)0

합법적입니다. 그러나 제 생각에는 void*캐스트가 여기에 있으므로 다음과 같은 진술이 있습니다.

int x = NULL;

대부분의 시스템에서 컴파일러 경고를 생성합니다. C ++에서는 void*캐스트없이 암시 적으로 a 를 다른 포인터 형식으로 암시 적으로 변환 할 수 없기 때문에 이것은 합법적이지 않습니다 . 예를 들어, 이것은 불법입니다.

int* ptr = (void*)0; // Legal C, illegal C++

그러나 이것은 코드가

int x = NULL;

합법적 인 C ++입니다. 이것과 뒤 따르는 혼란 때문에 (그리고 나중에 보여지는 또 다른 경우), C ++ 11부터 nullptr널 포인터를 나타내는 키워드가 있습니다 :

int* ptr = nullptr;

이것은 위의 문제가 없습니다.

nullptr0 이상의 또 다른 장점은 C ++ 유형 시스템에서 더 잘 작동한다는 것입니다. 예를 들어 다음 두 가지 기능이 있다고 가정합니다.

void DoSomething(int x);
void DoSomething(char* x);

내가 전화하면

DoSomething(NULL);

다음과 같습니다.

DoSomething(0);

DoSomething(int)예상 대신 호출 합니다 DoSomething(char*). 그러나으로 nullptr, 나는 쓸 수

DoSomething(nullptr);

그리고 DoSomething(char*)예상대로 함수를 호출합니다 .

마찬가지로, a가 vector<Object*>있고 각 요소를 null 포인터로 설정 한다고 가정합니다 . std::fill알고리즘을 사용하여

std::fill(v.begin(), v.end(), NULL);

그러나 템플릿 시스템은 포인터가 아닌 포인터 NULL취급하기 때문에 컴파일되지 않습니다 int. 이 문제를 해결하려면 다음과 같이 작성해야합니다.

std::fill(v.begin(), v.end(), (Object*)NULL);

이것은 추악하고 템플릿 시스템의 목적에 다소 위배됩니다. 이 문제를 해결하려면 다음을 사용할 수 있습니다 nullptr.

std::fill(v.begin(), v.end(), nullptr);

그리고 nullptrnull 포인터 (특히 std::nullptr_t)에 해당하는 유형이있는 것으로 알려져 있으므로 올바르게 컴파일됩니다.

도움이 되었기를 바랍니다!


C에서 NULL구현 정의 "널 포인터 상수"로 확장됩니다. 널 포인터 상수는 값이 0 인 정수 상수 표현식이거나 void*. 따라서 C 구현은 NULL0또는로 정의 할 수 있습니다 ((void*)0).

C ++에서 널 포인터 상수에 대한 규칙은 다릅니다. 특히, ((void*)0)은 (는) C ++ 널 포인터 상수가 아니므로 C ++ 구현에서는 NULL그런 방식으로 정의 할 수 없습니다 .


C 언어는 마이크로 프로세서를 더 쉽게 프로그래밍 할 수 있도록 만들어졌습니다. AC 포인터는 데이터 주소를 메모리에 저장하는 데 사용됩니다. 포인터에 유효한 값이 없음을 나타내는 방법이 필요했습니다. 모든 마이크로 프로세서가 부팅에 해당 주소를 사용했기 때문에 주소 0이 선택되었습니다. 다른 용도로는 사용할 수 없기 때문에 유효한 값이없는 포인터를 나타내는 데 0이 좋은 선택이었습니다. C ++는 C와 역 호환되므로 해당 규칙을 상속받습니다.

포인터로 사용할 때 0을 캐스팅해야하는 요구 사항은 최근 추가 기능 일뿐입니다. 이후 세대의 C는 더 엄격한 (그리고 더 적은 오류)를 원했기 때문에 구문에 대해 더 현명 해지기 시작했습니다.

참고 URL : https://stackoverflow.com/questions/7016861/why-are-null-pointers-defined-differently-in-c-and-c

반응형