C ++에서 포인터에 NULL 또는 0을 사용합니까?


194

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 포인터를 거의 사용하지 않지만 때로는 여전히 포인터가 필요하다는 것을 추가해야합니다.


9
널 (null)이 내부적으로 0인지 여부에 상관없이 false로 평가하는 데 널 포인터가 필요하지 않습니까?
Mooing Duck

답변:


186

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

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

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

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


7
Bjarne은 C ++ 0x가 새로운 null 유형 작업을 시작하기 전에 이것을 썼습니다. 플랫폼에서 사용할 수있을 때이 유형에 NULL이 사용되는 경우가 될 것입니다. 이에 대한 일반적인 합의에 C 변경이 표시됩니다.
Richard Corden

122

나는 이것에 대한 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을 사용하는 사람이라면 누구나 정규 표현식에 대해 잘 알고 있기를 바랍니다.


1
이것들은 다소 좋은 점입니다. 인정해야합니다. C ++ 0x가 null 유형을 갖게되어 기쁩니다. 많은 것들을 더 깨끗하게 만들 것이라고 생각합니다.
Rob

2
@Richard, 왜 반대? Meyers nullptr_t를 사용할 수 있으며 0x가 사용 가능 해지면를 제거 #include하고 안전한면에 보관하십시오.
fnieto-페르난도 니에 토

15
#define NULL nullptr위험한 것 같습니다. 더 좋든 나쁘게도 많은 레거시 코드는 0이 아닌 다른 것에 NULL을 사용합니다. 예를 들어, 핸들은 종종 일부 정수 유형으로 구현되며 NULL드물게 설정 되지 않습니다. 나는를 제로 종료 자로 NULL설정하는 것과 같은 남용을 보았습니다 char.
Adrian McCarthy

8
@AdrianMcCarthy : 코드가 자동으로 컴파일되어 다른 의미를 가질 위험이있는 경우에만 위험하다고 말합니다. 나는 이것이 사실이 아니라고 확신하므로 실제로 NULL의 모든 잘못된 사용이 감지됩니다.
Richard Corden

3
@RichardCorden : 음, 그 다른 용도 NULL가 실제로 잘못 되었다고 가정합니다 . 많은 API가 오랫동안 NULL핸들과 함께 사용되어 왔으며, 실제로 많은 API 에서 문서화 된 사용법입니다. 그것들을 갑자기 깨뜨리고 그들이 잘못하고 있다고 선언하는 것은 실용적이지 않습니다.
Adrian McCarthy가

45

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


28
0은 구현 세부 사항이 아닙니다. 표준은 0을 정의하여 비트 패턴이 널 포인터를 나타내는 것이 무엇이든 정의합니다.
Ferruccio

5
마치 ..!! 야, C ++은 저급 언어입니다! 0을 사용하면 잘 알려진 관용구입니다.
hasen

8
나는 그것이 표준의 일부라는 것을 이해합니다. 코드를 읽는 한 구현 세부 사항입니다. 독자는 "NULL 포인터"가 "0이 아니라 NULL 포인터를 의미하며, 산술 할 수있는 숫자가 아니라"라고 생각해야합니다.
Andy Lester

2
+1. 앤디와 합의했습니다. @Ferruccio, 구현 세부 프로그래머의 아이디어는 컴파일러의 구현과 동일하지 않습니다 정의
사용자

복잡한 헤더가없는 일반 코드에서 NULL을 사용하면 "이 범위에서 NULL이 정의되지 않았습니다"라는 오류가 발생합니다.
ArtificiallyIntelligence

38

나는 항상 사용합니다 :

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

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


25
암시 적 타입 캐스트를 피하기 위해 아마 수레에 0.0F를 사용해야합니다.
EvilTeach

35

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

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

static const int nullptr = 0;

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


4
NULL을 사용하면보다 이식성이 뛰어납니다. 'nullptr'은 일부 플랫폼에서는 사용할 수 있으며 다른 플랫폼에서는 사용할 수 없습니다. 여기서 솔루션은 선언 주위에 전처리기를 사용하여 필요할 때만 존재하도록 보장해야합니다. NULL은이를 자동으로 수행합니다.
Richard Corden

6
동의하지 않습니다. 컴파일러가 따라 잡을 때까지 단기적으로 이식성이 떨어질 것입니다. 장기적으로는 휴대하기 쉽고 조금 더 읽기 쉽습니다.
Ferruccio

4
또한 C ++ 0x가 아닌 컴파일러에 대해 항상 #define nullptr NULL을 지정할 수 있습니다.
Anteru December

20
    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아마도 휴대용이 아니며 안전하지 않습니다. Stroustrup의 FAQ#define NULL 0 에 따르면 여전히 플랫폼이있을 수 있습니다 ( 상위 질문에 인용 된 NULL 또는 0?을 사용해야 하며 첫 번째 검색 결과 중 하나입니다). 적어도 이전 C ++에서는 0포인터 컨텍스트에서 특별한 개념적 의미가 있습니다. 비트에 대해 구체적으로 생각해서는 안됩니다. 또한 다른 정수 상황에서 (참고 short, int, long long) " sizeof(0)"다른 것입니다. 나는이 대답이 약간 잘못 안내되었다고 생각합니다.
FooF

(개인적으로 일상 생활에서의 C 프로그래머로, 나는 사람들이 사용하고자하는 이유를 이해하기 위해 질문을 방문했다 NULL대신 (char *)0, (const char *)0또는 (struct Boo *)0또는 (void *)0또는 의도를 더 명확하게 표현에 무엇이든 -. 너무 복잡) 내 의견으로는 (없이)
FooF

투표하십시오. msvc2013 C 컴파일러에서 발생합니다. 64 비트에서 포인터로 변환 할 때 0은 NULL 포인터임을 보증하지 않습니다.
pengMiao

16

내가 올바르게 호출하면 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.


15

나는 역사가 말하고 0을 사용하는 것에 찬성하여 주장하는 사람들이 잘못되었다고 말할 것입니다 (Bjarne Stroustrup 포함). 0을지지하는 주장은 대부분 미학과 "개인 취향"이었습니다.

새로운 nullptr 유형으로 C ++ 11을 만든 후 일부 컴파일러는 0이 포인터가 아니기 때문에 포인터 인수가있는 함수에 0을 전달하는 것에 대해 불평하기 시작했습니다 (기본 매개 변수 사용).

코드가 NULL을 사용하여 작성된 경우 코드베이스를 통해 간단한 검색 및 바꾸기를 수행하여 대신 nullptr로 만들 수 있습니다. 포인터로 0을 선택하여 작성된 코드가 붙어 있으면 업데이트하는 것이 훨씬 지루합니다.

그리고 지금 C ++ 03 표준에 새로운 코드를 작성해야하고 nullptr을 사용할 수 없다면 NULL을 사용해야합니다. 향후 업데이트가 훨씬 쉬워 질 것입니다.


11

나는 보통 0을 사용한다. 나는 매크로를 좋아하지 않는다. 그리고 당신이 사용하고있는 어떤 써드 파티 헤더가 NULL을 이상한 것으로 재정의하지 않는다는 보장은 없다.

C ++에서 nullptr 키워드를 얻을 때까지 Scott Meyers와 다른 사람들이 제안한대로 nullptr 객체를 사용할 수 있습니다.

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

자세한 내용은 Google "nullptr"을 참조하십시오.


9
0 이외의 (또는 (void*)0C 코드로 컴파일되는 경우)에 NULL을 정의하는 타사 라이브러리는 문제를 요구하는 것이므로 사용해서는 안됩니다.
Adam Rosenfield

2
실제로 NULL을 재정의하는 라이브러리를 본 적이 있습니까? 이제까지? 그러한 라이브러리가 존재한다면, NULL을 재정의하기에 멍청한 라이브러리를 사용하는 것과 같이 재정의 된 NULL보다 더 큰 문제가 있습니다.
Andy Lester

1
10 년 전에는 NULL을 정의한 타사 헤더 (Orbix 또는 ObjectStore)를 처리해야한다는 점을 모호하게 기억합니다. 나는 여러 타사 헤더를 windows.h와 함께 사용하려고 며칠과 밤을 낭비 한 후 병리학 적 매크로에 대한 증오를 가지고 있다고 생각합니다.
jon-hanson

2
"매크로를 좋아하지 않음"은 객체와 같은 #define에 대한 이상한 비판입니다. C 프리 프로세서가 마음에 들지 않는다고 말할 수 있습니까?
앤드류 프록

@Andrew- NULL오버 의 유일한 장점 (type *)0은 검색 가능성입니다. 그렇지 않으면 C 관용구가 아니라면 불필요한 난독 화처럼 보입니다. 나는 개인적으로 NULL모든 곳 에서 퍼지는 관용구 가 죽어야 한다고 생각합니다 . NULL내 의견으로는 쓸모없는 매크로입니다. Occam의 면도기는 여기서 할 일이 있습니다 ...
FooF

11

한 번 0은 유효한 주소이고 NULL은 특수 8 진수 값으로 정의 된 컴퓨터에서 작업했습니다. 해당 머신 (0! = NULL)에서 다음과 같은 코드

char *p;

...

if (p) { ... }

예상대로 작동하지 않습니다. 당신은 쓸 수 있었다

if (p != NULL) { ... }

요즘 대부분의 컴파일러가 NULL을 0으로 정의한다고 생각하지만 그 시절의 교훈을 여전히 기억합니다. NULL은 반드시 0이 아닙니다.


26
호환되는 컴파일러를 사용하지 않았습니다. 표준에 따르면 NULL 0이며 컴파일러는 포인터 컨텍스트에서 0을 아치에 대한 적절한 true NULL 값으로 변환해야 한다고 말합니다 .
Evan Teran

17
네, 맞아요. 이것은 ANSI가 C 표준을 만들기 전에 80 년대 중반이었습니다. 준수와 같은 것은 없었으며 컴파일러 작성자는 언어를 자유롭게 해석 할 수있었습니다. 그것이 표준이 필요한 이유입니다.
mxg

9

나는 표준이 NULL == 0을 보장한다고 생각하므로 둘 중 하나를 수행 할 수 있습니다. 나는 의도를 문서화하기 때문에 NULL을 선호합니다.


중첩 구조가있는 경우 foo.bar_ptr = (Bar *) 0의도가보다 명확하게 표현된다고 생각 foo.bar_ptr = NULL합니다. 이 습관은 또한 컴파일러가 오해 오류를 포착 할 수 있도록합니다. 나를 위해, 그것이 포인터 라는 것을 알고 있다면 foo.bar_ptr = 0사용뿐만 아니라 의도를 표현합니다 . NULLfoo.bar_ptr
FooF

9

0 또는 NULL을 사용하면 동일한 효과가 있습니다.

그렇다고해서 이것이 좋은 프로그래밍 관행이라는 것을 의미하지는 않습니다. 성능에 차이가 없다는 것을 고려할 때, 불가지론 적 / 추상적 대안에 대해 저수준 인식 옵션을 선택하는 것은 나쁜 프로그래밍 관행입니다. 코드를 읽는 사람이 사고 과정을 이해하도록 도와주십시오 .

NULL, 0, 0.0, '\ 0', 0x00 및 whatelse는 모두 같은 것으로 변환되지만 프로그램에서 다른 논리 엔터티입니다. 그것들은 그대로 사용해야합니다. NULL은 포인터, 0은 수량, 0x0은 비트가 흥미로운 값 등입니다. 컴파일 여부에 관계없이 포인터에 '\ 0'을 할당하지 않습니다.

일부 커뮤니티는 환경 계약을 위반하여 환경에 대한 심층적 인 지식을 보여줄 것을 권장합니다. 그러나 책임있는 프로그래머는 유지 관리 가능한 코드를 작성하고 그러한 관행을 코드에서 유지하십시오.


5

Stroustroup을 포함하여 아무도 이상하게 언급하지 않았습니다. 것으로 나타났습니다 기준과 미학 아무도에 대해 많은 이야기를하는 동안 위험한 사용 0NULL경우 아키텍처에 변수 인수 목록에서, 예를 들어,의 대신 sizeof(int) != sizeof(void*). Stroustroup과 마찬가지로 0미학적 이유로 선호 하지만 유형이 모호한 곳에서는 사용하지 않도록주의해야합니다.


그리고 그 위험한 곳에서 당신은 여전히 사용할 수 있습니다 0당신이 지정 제공 0뜻 - 예를 들어 (int *)0, (char *)0, (const char *)0또는 (void *)0또는 (unsigned long long) 0또는 무엇 이건. 이것은 제 생각에보다 분명한 의도를 나타냅니다 NULL.
FooF

1
무엇을 NULL의미 하는지 모른다면 물론 입니다.
Michael Krelin-해커

나는 개인적으로 정확한 유형을 사용할 수있을 때 불필요하게 무언가를 던지는 것이 약간 불쾌하다는 것을 (void *)알았습니다. 포인터의 경우와 비슷하기 때문에 의도적으로 목록에 (일반적으로) 64 비트 정수의 예를주었습니다. 또한 이전 C ++에 대한 기억 이 정확하다고 정의 NULL하면 0(C ++로 프로그래밍 한 지 몇 년이 지났음) 프로그램 정확성이 향상되지 않습니다. 최신 C ++ 표준은 다행히 nullptr키워드를 제공 하므로 NULL최신 C ++을 작성할 때이 어수선 함과 전체 논쟁을 제거 할 수 있습니다 .
FooF

그렇기 때문에 캐스팅 (void*)이로 추상화되었습니다 NULL. 그리고 NULL실제로 당시의 의도를 매우 명확하게 가장을 표현한다. 그리고 나는 당신의 기억이 잘못되었다고 생각합니다. 표준에 대해서는 확실하지 않지만 실제로는 표준이라고 생각합니다 (void*)0. 그리고 예, nullptr좋은 예 NULL입니다. 타입을 지정하지 않고 null 포인터를 지정 하는 것과 같은 것입니다.
Michael Krelin-해커

1
일부 플랫폼에서 @FooF – 아마도. 실제로는 효과가 있었으므로 포인터로 정의 된 것 같습니다. 견고성에 관해서는, 그렇습니다. 나는 처음에 언급 한 의도를 표현하는 것과 관련된 nullptr메시지 를 사용 하는 것과 같은 메시지 를 사용 합니다 NULL. ( NULL현대 gcc수율 __null에 상관없이 전처리 ).
Michael Krelin-해커

4

가능한 경우 C ++ 참조를 사용하여 전체 질문을 피하려고합니다. 오히려

void foo(const Bar* pBar) { ... }

당신은 종종 쓸 수 있습니다

void foo(const Bar& bar) { ... }

물론 이것이 항상 작동하는 것은 아닙니다. 그러나 널 포인터는 과도하게 사용될 수 있습니다.


3

나는 이것에 Stroustrup을 사용하고 있습니다 :-) NULL은 언어의 일부가 아니기 때문에 0을 선호합니다.


3

대부분 개인적인 선호도, NULL이라는 주장을 할 수는 있지만 객체가 현재 아무것도 가리 키지 않는 포인터라는 것을 분명히 알 수 있습니다.

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC에서 표준은 NULL이 0 일 필요가 없으므로 <stddef.h>에 정의 된 것을 사용하는 것이 컴파일러에 가장 적합 할 것입니다.

논증의 또 다른 측면은 논리 비교 (암시 적 캐스트에서 부울로)를 사용해야하는지 또는 NULL에 대한 명시 적 검사를 사용해야하는지 여부이지만 가독성도 있습니다.


3

의도가 값이 산술 값이 아닌 포인터를 나타내는 지 확인하기 때문에 NULL을 사용하는 것이 좋습니다. 그것이 매크로라는 사실은 불행한 일이지만, 너무 광범위하게 뿌리 내려 있기 때문에 위험이 거의 없습니다 (누군가가 실제로 무언가를하지 않는 한). 키워드가 처음부터 키워드 였으면 좋겠지 만 어떻게해야합니까?

즉, 포인터를 진리 값으로 사용하는 데 아무런 문제가 없습니다. NULL과 마찬가지로 뿌리 깊은 관용구입니다.

C ++ 09는 오래되었다고 생각되는 nullptr 구문을 추가합니다.


1

나는 항상 0을 사용합니다. 실제로 C ++을 처음 배울 때 0을 사용하여 권장되는 것을 읽었 기 때문에 항상 그렇게 생각했습니다. 이론적으로 가독성에는 혼란스런 문제가있을 수 있지만 실제로 수천 번의 작업 시간과 수백만 줄의 코드에서 이러한 문제를 한 번도 경험 한 적이 없습니다. Stroustrup이 말했듯이, 표준이 nullptr이 될 때까지 실제로 개인적인 미학적 문제 일뿐입니다.


1

누군가 나에게 한 번 말했다 ... 나는 NULL을 69로 다시 정의 할 것입니다. 그 이후로 나는 그것을 사용하지 않습니다 : P

코드가 매우 취약합니다.

편집하다:

표준의 모든 것이 완벽하지는 않습니다. 매크로 NULL은 구현이 정의한 C ++ 널 포인터 상수이며 C NULL 매크로와 완전히 호환되지 않습니다. 암시 적 유형 숨김 외에는 쓸모없고 오류가 발생하기 쉬운 도구로 변환됩니다.

NULL은 널 포인터가 아니라 O / OL 리터럴로 작동합니다.

다음 예제는 혼란스럽지 않습니다.

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

새로운 표준에서는 std :: nullptr_t로 나타납니다.

새로운 표준을 기다리지 않고 nullptr을 사용하려면 Meyers가 제안한 것과 같은 적절한 것을 사용하십시오 (jon.h 주석 참조).


5
NULLC ++ 표준의 잘 정의 된 부분입니다. 표준 매크로를 재정의하려는 사람들이 프로젝트에서 코드를 편집하도록 허용하면 코드가 취약 해집니다. 사용 NULL하지 않습니다.
CB Bailey

1

글쎄, 나는 가능할 때마다 0 또는 NULL 포인터를 전혀 사용하지 않는다고 주장한다.

그것들을 사용하면 조만간 코드에서 세그먼테이션 오류가 발생합니다. 내 경험에 따르면, gereral의 포인터는 C ++에서 가장 큰 버그 소스 중 하나입니다.

또한 코드 전체에서 "널이 아닌 경우"문으로 이어집니다. 항상 유효한 상태에 의존 할 수 있다면 훨씬 좋습니다.

거의 항상 더 나은 대안이 있습니다.


2
보장 된 세그먼트 오류 (그리고이 되어 당신이 역 참조하면 현대적인 시스템에 보장은 0)는 유용한 디버깅. 랜덤 쓰레기를 역 참조하고 결과를 누가 알 수 있는지를 얻는 것보다 훨씬 낫습니다.
궤도에서 가벼움 경주

-4

포인터를 0으로 설정하는 것은 분명하지 않습니다. 특히 C ++ 이외의 언어를 사용하는 경우. 여기에는 C뿐만 아니라 Javascript도 포함됩니다.

나는 최근에 다음과 같은 코드로 결정했다.

virtual void DrawTo(BITMAP *buffer) =0;

처음으로 순수한 가상 기능. 나는 그것이 일주일 동안 마술 지베 르자 쉬라고 생각했다. 내가 기본적으로 함수 포인터를 null(가상 함수는 대부분의 경우 C ++의 경우 함수 포인터이기 때문에) 함수 포인터를 설정한다는 것을 깨달았을 때 나는 스스로 발로 차었다.

virtual void DrawTo(BITMAP *buffer) =null;

내 새로운 눈에 적절한 간격을 두지 않고 엉망인 것보다 덜 혼란 스러웠을 것입니다. 실제로 C ++이 null소문자 false 및 true를 사용하는 것처럼 소문자를 사용하지 않는 이유가 궁금 합니다.


일반적으로 포인터의 경우 NUL1을 0보다 선호합니다. 그러나 '= 0;' C ++에서 순수한 가상 함수를 선언하는 관용적 방법입니다. '= NULL;'을 사용하지 말 것을 강력히 권합니다. 이 특별한 경우에.
danio

이것은 StackOverflow에 대한 가장 재미있는 의견입니다. 당신이 준 예제는 포인터가 아닌 순수한 가상 함수에 대한 문법이라는 것을 이미 알고있을 것입니다. 그리고 @danio가 맞습니다. 순수한 가상 함수에는 NULL을 사용해서는 안됩니다.
sgowd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.