[CppCoreGuidelines] not_null - null이 될 수 없는 값 구분하기
Null pointer dereferencing 은 C++을 사용하다 보면 자주 발생하는 문제다. 값이 없을 수 있는 객체를 지칭할 때 포인터를 사용하고 값이 없는 상태를 null로 표현하는 C++에서 이를 근본적으로 회피할 방법은 없다. 따라서 null일 수 있는 포인터는 사용하기 전에 항상 체크하고 사용해야 한다. 하지만 모든 포인터가 null이 될 가능성을 가지고 있는 건 아니다. 로직 상으로 일부 포인터들은 null이 될 수 없다. 반드시 존재하는 객체의 주소를 가리키고 있을 수도 있고, 이미 null인지 체크한 포인터일 수도 있다. 이런 포인터까지 사용하기 전에 null인지 체크하고 사용하는 건 귀찮고, 추가 비용만 들어간다. 이런 경우 과거에는 레퍼런스 를 이용했다. 레퍼런스는 선언 시 반드시 초기화해야 하므로 레퍼런스가 가리키는 객체는 null이 아닐 것이라는 생각에서였다. 하지만 사실 레퍼런스도 null pointer dereferencing에 대해서 그다지 안전하지 않다. 위와 같은 함수를 아래처럼 포인터를 받아서 부르는 경우를 생각해보자. 위의 코드는 여전히 null pointer dereferencing 문제를 가진다. f5 가 인자로 받은 t 의 null 체크를 하지 않고 f4 로 넘겼기 때문이다. 게다가 레퍼런스로 부르는 방식은 modern c++에 스마트 포인터가 들어오면서 일반적으로 사용할 수 있는 방법은 아니게 됐다. shared_ptr 과 unique_ptr 은 포인터의 semantic을 그대로 따르기 때문에 null이 될 수 있다. 하지만 null이 될 수 없는 shared_ptr 과 unique_ptr 를 reference로 표현할 수 없다. 따라서 포인터 시멘틱을 따르는 타입이지만, null이 될 수 없는 객체를 표현할 일반적인 방법이 필요하다. C++ Core Guidelines 는 null이 될 수 없는 포인터 계열의 변수는 not_null<T> 이라는 클래스를 사용하기를 권장한다. no...