C ++에서 포인터에 NULL 또는 0을 사용합니까? 할 수 없어서 void*쓸모가

C ++가 C 위에 볼트로 고정되었을 때 C ++의 초기에는로 정의 된 NULL을 사용할 수 없었습니다 (void*)0. 이외의 다른 포인터에는 NULL을 할당 할 수 없어서 void*쓸모가 없었습니다. 그 당시에 0는 널 포인터에 0 을 사용하는 것이 허용되었습니다 .

오늘날까지 나는 0을 널 포인터로 계속 사용했지만 내 주변 사람들은을 사용해야한다고 주장합니다 NULL. 나는 개인적 NULL으로 기존 값에 이름 ( ) 을 주면 아무런 이점이 없으며 포인터를 진리 값으로 테스트하고 싶습니다.

if (p && !q)
  do_something();

그런 다음 0을 사용하는 것이 더 합리적입니다 (사용하는 것처럼 NULL논리적으로 사용할 수 없음 -0이 아닌 경우 p && !q명시 적으로 비교해야 함 ).NULLNULLNULL

NULL보다 0을 선호하는 객관적인 이유가 있습니까 (또는 그 반대), 아니면 모두 개인 취향입니까?

편집 : RAII와 예외를 제외하고는 0 / NULL 포인터를 거의 사용하지 않지만 때로는 여전히 포인터가 필요하다는 것을 추가해야합니다.



답변

여기 Stroustrup이 취한 것입니다 : C ++ Style and Technique FAQ

C ++에서 정의 NULL는 0이므로 미적 차이 만 있습니다. 나는 매크로를 피하는 것을 선호하므로 0을 사용합니다. 또 다른 문제 NULL는 사람들이 때로는 0과 다르거 나 정수가 아니라고 잘못 생각한다는 것입니다. 사전 표준 코드에서 NULL때로는 부적절한 것으로 정의되었으므로 피해야했습니다. 요즘 덜 일반적입니다.

널 포인터의 이름을 지정해야하는 경우이를 호출하십시오 nullptr. 그것이 C ++ 11에서 호출되는 것입니다. 그러면 nullptr키워드가됩니다.

즉, 작은 물건을 땀을 흘리지 마십시오.


답변

나는 이것에 대한 Bjarne의 입장과 모순된다고 믿는 몇 가지 주장 (그중 하나가 비교적 최근의 주장)이 있습니다.

  1. 의도 문서

를 사용하면 NULL사용에 대한 검색 이 가능하며 컴파일러가 포인터를 해석하는지 여부에 관계없이 개발자 NULL 포인터 를 사용 하려고 한다는 것을 강조합니다 NULL.

  1. 포인터와 ‘int’의 과부하는 상대적으로 드 rare니다

모두가 인용하는 예는 다음과 같습니다.

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

그러나 적어도 내 의견으로는 위의 문제는 널 포인터 상수에 NULL을 사용한다는 것이 아니라 매우 다른 종류의 인수를 취하는 ‘foo’의 과부하가 있다는 것입니다. int다른 유형은 모호한 호출을 초래하고 유용한 컴파일러 경고를 생성하므로 매개 변수 도 역시 커야합니다.

  1. 오늘날 분석 도구가 도움이 될 수 있습니다!

C ++ 0x가없는 경우에도 오늘날 NULL포인터를 사용하고 있고 0적분 유형에 사용 되는지 확인하는 도구가 있습니다 .

  1. C ++ 11 에는 새로운 std::nullptr_t유형이 있습니다.

이것은 테이블에 대한 최신 인수입니다. 의 문제 0와는 NULL적극적으로되는 C ++ 0X에 대한 해결, 당신이 제공하는 모든 구현을 보장 할 수있다 NULL, 그들이 할 것이라는 매우 먼저입니다 :

#define NULL  nullptr

NULL대신에 사용 하는 사람들에게는 0노력이 거의 또는 전혀없이 유형 안전성이 향상 될 것 NULL입니다 0. 0오늘 …. erm을 사용하는 사람이라면 누구나 정규 표현식에 대해 잘 알고 있기를 바랍니다.


답변

NULL을 사용하십시오. NULL은 의도를 보여줍니다. 그것이 0이라는 것은 중요하지 않은 구현 세부 사항입니다.


답변

나는 항상 사용합니다 :

  • NULL 포인터
  • '\0' 문자
  • 0.0 수레와 복식

0은 괜찮을 것입니다. 시그널링 의도의 문제입니다. 즉, 나는 그것에 대해 항문이 아닙니다.


답변

오래 전에 0을 선호하여 (대부분의 다른 매크로와 마찬가지로) NULL 사용을 중단했습니다. 매크로를 가능한 많이 피하고 싶었을뿐만 아니라 C 및 C ++ 코드에서 NULL이 과도하게 사용 된 것 같습니다. 포인터뿐만 아니라 0 값이 필요할 때마다 사용되는 것으로 보입니다.

새로운 프로젝트에서 나는 이것을 프로젝트 헤더에 넣었다.

static const int nullptr = 0;

이제 C ++ 0x 호환 컴파일러가 도착하면 그 줄을 제거하면됩니다. 이것의 좋은 장점은 Visual Studio가 이미 nullptr을 키워드로 인식하고 적절히 강조 표시한다는 것입니다.


답변

    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

이 이야기의 교훈. 포인터를 다룰 때는 NULL을 사용해야합니다.

1) 의도를 선언합니다 (변수가 포인터인지 숫자 유형인지 알아 내려고 모든 코드를 검색하지 마십시오).

2) 가변 인수를 기대하는 특정 API 호출에서는 인수 목록의 끝을 나타 내기 위해 NULL 포인터를 사용합니다. 이 경우 NULL 대신 ‘0’을 사용하면 문제가 발생할 수 있습니다. 64 비트 플랫폼에서 va_arg 호출은 64 비트 포인터를 원하지만 32 비트 정수만 전달합니다. 다른 32 비트에 의존하여 제로화되는 것처럼 보입니다. 나는 그렇게 유쾌하지 않은 특정 컴파일러 (예 : Intel의 ICPC)를 보았습니다.


답변

내가 올바르게 호출하면 NULL은 내가 사용한 헤더에서 다르게 정의됩니다. C의 경우 (void *) 0으로 정의되고 C ++의 경우 0으로 정의됩니다. 코드는 다음과 같습니다.

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

개인적으로 여전히 NULL 값을 사용하여 널 포인터를 나타내므로 일부 정수 유형이 아닌 포인터를 사용하고 있음을 명시 적으로 나타냅니다. 예 내부적으로 NULL 값은 여전히 ​​0이지만 그렇게 표시되지는 않습니다.

또한 정수를 부울 값으로 자동 변환하는 것에 의존하지 않지만 명시 적으로 비교합니다.

예를 들어 다음을 사용하는 것이 좋습니다.

if (pointer_value != NULL || integer_value == 0)

오히려

if (pointer_value || !integer_value)

이것은 C ++ 11에서 모두 수정되어 간단히 nullptr대신 사용할 수 있으며 이는 NULL또한 nullptr_t유형입니다 nullptr.