C / C ++에서 NULL 포인터 확인 [닫기]

최근 코드 검토에서 기고자는 NULL포인터에 대한 모든 검사가 다음과 같은 방식으로 수행되도록 노력하고 있습니다.

int * some_ptr;
// ...
if (some_ptr == NULL)
{
    // Handle null-pointer error
}
else
{
    // Proceed
}

대신에

int * some_ptr;
// ...
if (some_ptr)
{
    // Proceed
}
else
{
    // Handle null-pointer error
}

나는 “이 포인터가 NULL이 아닌지 확인하십시오”라는 말의 의미에서 그의 방식이 좀 더 명확하다는 데 동의하지만,이 코드를 작업하는 사람은 포인터 변수를 사용하면 if문이 암시 적으로 검사하고 NULL있습니다. 또한 두 번째 방법은 ilk의 버그를 도입 할 가능성이 적습니다.

if (some_ptr = NULL)

그것은 찾아서 디버깅하는 데 절대적으로 고통입니다.

어떤 방법을 선호하고 왜?



답변

내 경험상 양식 if (ptr)또는 시험 if (!ptr)이 선호됩니다. 그것들은 심볼의 정의에 의존하지 않습니다 NULL. 실수로 할당 할 수있는 기회를 제공하지 않습니다. 그리고 그들은 명확하고 간결합니다.

편집 : SoapBox는 주석에서 지적한 auto_ptr것처럼 포인터 역할을하고 bool정확하게이 관용구를 활성화 하기 위해 변환을 제공하는 객체 와 같은 C ++ 클래스와 호환됩니다 . 이러한 개체의 경우 명시 적으로 비교하려면 NULL다른 의미 부작용이 있거나 bool변환이 암시 하는 단순 존재 확인보다 비쌀 수있는 포인터로의 변환을 호출해야 합니다.

불필요한 텍스트가없는 의미를 나타내는 코드를 선호합니다. 중복 특이성 if (ptr != NULL)과 동일한 의미를 지니고 if (ptr)있습니다. 다음 논리는 글을 쓰는 if ((ptr != NULL) == TRUE)것이고, 그런 식으로 광기가 있습니다. C 언어는 부울 테스트 분명하다 if, while나 아닌 값의 의미 특정을 가지고 같은 사실과 제로는 false입니다. 중복성은 명확하지 않습니다.


답변

if (foo)충분히 명확하다. 그걸 써.


답변

이것부터 시작하겠습니다 : 일관성이 중요합니다. 코드 기반의 일관성보다 결정이 덜 중요합니다.

C ++에서

C ++에서 NULL은 0 또는 0L로 정의됩니다.

당신이 읽은 경우 언어 프로그래밍은 C ++ 사용하여 제안 비얀 스트로브 스트 룹을 0방지하기 위해 명시 적으로 NULL임무를 수행 할 때 매크로를 그가 비교와 동일 한 경우에, 잘 모르겠어요 내가 책을 읽을 수 있기 때문에, 나는 그가 단지했다고 생각하지만, 그것은을이었다 if(some_ptr)명백한 비교가 없지만 나는 그것에 모호합니다.

그 이유는 NULL매크로가 (거의 모든 매크로와 마찬가지로) 기만적이기 때문에 실제로 0문자 그대로이며 이름에서 알 수 있듯이 고유 한 유형이 아닙니다. 매크로를 피하는 것은 C ++의 일반적인 지침 중 하나입니다. 반면에 0정수처럼 보이며 포인터와 비교하거나 포인터에 할당 할 때는 그렇지 않습니다. 개인적으로 나는 어느 쪽이든 갈 수 있지만 일반적으로 나는 명백한 비교를 건너 뜁니다 (어떤 사람들은 이것을 싫어하기 때문에 아마도 변경 사항을 제안하는 기고자가있는 것입니다).

개인적인 감정에 관계없이 이것은 올바른 방법이 없기 때문에 가장 악한 선택입니다.

이것은 명확하고 일반적인 관용구이며 선호합니다. 비교 중에 실수로 값을 할당 할 가능성이 없으며 명확하게 읽습니다.

if(some_ptr){;}

이것이 some_ptr포인터 유형 이라는 것을 알면 분명 하지만 정수 비교처럼 보일 수도 있습니다.

if(some_ptr != 0){;}

이것은 명백한 일이며, 일반적인 경우에 의미 NULL0있습니다.

if(some_ptr != NULL){;}

C ++ 0x에는 명시적이고 정확하기 때문에 선호되는 방법 인 nullptr이 있습니다. 우연한 할당에주의하십시오.

if(some_ptr != nullptr){;}

C ++ 0x로 마이그레이션 할 때까지 사용하는 방법 중 하나를 걱정하는 데 시간 낭비라고 주장 할 수 있습니다. 완전히 전달 된 일반적인 프로그래밍 문제와 함께 nullptr이 발명 된 이유는 모두 충분하지 않습니다 .) 가장 중요한 것은 일관성을 유지하는 것입니다.

C에서

C는 다른 짐승입니다.

C NULL에서 0 또는 ((void *) 0)으로 정의 될 수있는 C99는 구현 정의 널 포인터 상수를 허용합니다. 따라서 실제로 구현의 NULL 정의로 귀결되며 표준 라이브러리에서 검사해야합니다.

매크로는 매우 일반적이며 일반적으로 언어 및 기타 사항에서 일반 프로그래밍 지원의 결함을 보완하기 위해 많이 사용됩니다. 언어는 훨씬 단순하고 전처리기에 더 많이 의존합니다.

이 관점 NULL에서 C 에서 매크로 정의를 사용하는 것이 좋습니다 .


답변

나는을 사용 if (ptr)하지만 이것에 대해 논쟁 할 가치가 전혀 없다.

간결하기 때문에 내 방식이 마음에 들지만 다른 사람들 == NULL은 읽기 쉽고 명확하게 말합니다 . 나는 그들이 어디에서 왔는지 알았습니다. 여분의 물건에 동의하지 않기 때문에 더 쉽습니다. (매크로가 싫기 때문에 편견이 있습니다.) 당신에게 달려 있습니다.

나는 당신의 주장에 동의하지 않습니다. 조건부에서 할당에 대한 경고가 표시되지 않으면 경고 수준을 높여야합니다. 그렇게 간단합니다. (그리고 모든 것을 사랑하기 위해 그것들을 바꾸지 마십시오.)

C ++ 0X에 참고, 우리는 할 수있는 if (ptr == nullptr)나에게있는 않습니다 읽기 좋네요을. (다시 말하지만, 나는 매크로를 싫어합니다. 그러나 nullptr좋습니다.) 그래도 나는 if (ptr)그것이 익숙한 이유 때문에 여전히 그렇습니다.


답변

솔직히, 왜 중요한지 모르겠습니다. 어느 쪽이든 분명하고 C 또는 C ++에 대해 어느 정도 경험이있는 사람은 둘 다 이해해야합니다. 그러나 한 가지 의견 :

오류를 인식하고 함수를 계속 실행하지 않으려는 경우 (예 : 예외를 발생 시키거나 오류 코드를 즉시 반환하려는 경우) 가드 절로 만들어야합니다.

int f(void* p)
{
    if (!p) { return -1; }

    // p is not null
    return 0;
}

이렇게하면 “화살표 코드”를 피할 수 있습니다.


답변

개인적으로 저는 항상 if (ptr == NULL)의도를 밝히기 때문에 항상 사용해 왔지만이 시점에서는 습관 일뿐입니다.

=대신 ==적절한 경고 설정을 가진 적격 컴파일러가이를 대신 하여 사용 합니다.

중요한 점은 그룹에 일관된 스타일을 선택하고 고수하는 것입니다. 어떤 방법을 사용하든 결국에는 익숙해지며 다른 사람의 코드에서 작업 할 때 마찰이 사라지는 것을 환영합니다.


답변

foo == NULL연습 에 찬성하여 한 가지만 더 : foo예를 들어, a int *또는 a bool *인 경우, if (foo)수표는 실수로 포인트의 가치를 테스트하는 것으로 해석 될 수 있습니다 if (*foo). 여기서 NULL비교는 우리가 포인터에 대해 이야기하고 있음을 상기시킵니다.

그러나 나는 좋은 명명 규칙 이이 논쟁을 무시한다고 생각합니다.