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;
이것은 위의 문제가 없습니다.
nullptr
0 이상의 또 다른 장점은 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);
그리고 nullptr
null 포인터 (특히 std::nullptr_t
)에 해당하는 유형이있는 것으로 알려져 있으므로 올바르게 컴파일됩니다.
도움이 되었기를 바랍니다!
C에서 NULL
구현 정의 "널 포인터 상수"로 확장됩니다. 널 포인터 상수는 값이 0 인 정수 상수 표현식이거나 void*
. 따라서 C 구현은 NULL
로 0
또는로 정의 할 수 있습니다 ((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
'Programing' 카테고리의 다른 글
Scala의 "마법"기능 목록 (0) | 2020.10.30 |
---|---|
Where should I use defrecord in clojure? (0) | 2020.10.30 |
접두사가없는 targetNamespace 및 xmlns, 차이점은 무엇입니까? (0) | 2020.10.30 |
숫자를 두 번 또는 네 번 일치시키는 정규식 (0) | 2020.10.30 |
Fragment가 교체되어 백 스택에 배치 (또는 제거)되면 메모리에 유지됩니까? (0) | 2020.10.30 |