미리 정의된 널 포인터 상수

미리 정의된 널 포인터 상수 (Predefined null pointer constant)

C에서 "가리키는 대상이 없는 포인터"를 표현하는 방법으로는 사실상 NULL 매크로나 0을 써 왔어요. 그런데 C23부터는 **nullptr**라는 전용 상수가 생겼어요. 이 키워드는 전처리기 매크로가 아니라 언어가 직접 제공하는 미리 정의된 널 포인터 상수예요. 타입도 뚜렷해서, 정수 리터럴 0과 달리 포인터로 착각하기 쉬운 문맥을 안전하게 구분할 수 있어요.

출처: cppreference Predefined null pointer constant

본문

문법

nullptr (C23부터)

설명

키워드 **nullptr**는 미리 정의된 널 포인터 상수예요. 이는 타입 nullptr_t의 **비-lvalue(non-lvalue)**예요. nullptr은 포인터 타입이나 bool로 변환될 수 있는데, 변환 결과는 각각 그 타입의 널 포인터 값이나 false예요.

예제

nullptr의 복사본도 널 포인터 상수로 쓸 수 있다는 것을 보여줘요.

#include <stddef.h>
#include <stdio.h>

void g(int*)
{
    puts("Function g called");
}

#define DETECT_NULL_POINTER_CONSTANT(e) \
    _Generic(e,                         \
        void* : puts("void*"),           \
        nullptr_t : puts("nullptr_t"),   \
        default : puts("integer")        \
    )

int main()
{
    g(nullptr); // OK
    g(NULL); // OK
    g(0); // OK

    auto cloned_nullptr = nullptr;
    g(cloned_nullptr); // OK

    [[maybe_unused]] auto cloned_NULL = NULL;
//  g(cloned_NULL); // implementation-defined: maybe OK

    [[maybe_unused]] auto cloned_zero = 0;
//  g(cloned_zero); // Error

    DETECT_NULL_POINTER_CONSTANT(((void*)0));
    DETECT_NULL_POINTER_CONSTANT(0);
    DETECT_NULL_POINTER_CONSTANT(nullptr);
    DETECT_NULL_POINTER_CONSTANT(NULL); // implementation-defined
}

가능한 출력:

Function g called
Function g called
Function g called
Function g called
void*
integer
nullptr_t
void*

참조

  • C23 표준 (ISO/IEC 9899:2024):
    • 6.4.4.6 미리 정의된 상수 (p: 66)

더 알아보기

  • NULL은 구현 정의 널 포인터 상수(매크로 상수)예요. nullptr_t(C23)는 미리 정의된 널 포인터 상수 nullptr의 타입이에요.
  • 널 포인터 값과 0의 관계, 변환 규칙은 포인터와 변환 문서에서 이어져요.
  • cppreference의 Predefined null pointer constant 원문과 C++의 nullptr 문서를 비교해 보면 더 좋아요.