C++ 이야기 스물두번째: 0이 널포인터일까 ?

Posted at 2008. 8. 20. 01:17 // in S/W개발/C++ 이야기 // by 김윤수


"0이 널포인터일까요 ?"

다음 코드를 한 번 보시겠어요 ? 컴파일이 잘 될까요 ?

#include <boost/shared_ptr.hpp>

class Nil {
};

int
main()
{
  Nil* np = 0;
  boost::shared_ptr<Nil> p1(np);
  boost::shared_ptr<Nil> p2(0);
}

0이 널포인터라면 당연히 정상적으로 컴파일 되어야겠지요. 그런데 컴파일 에러가 발생합니다.

$ g++ -Wall -o null null.cpp -I../boost_1_36_0
null.cpp: In function ‘int main()’:
null.cpp:11: error: no matching function for call to ‘boost::shared_ptr<Nil>::shared_ptr(int)
../boost_1_36_0/boost/shared_ptr.hpp:178: note: candidates are: boost::shared_ptr<T>::shared_ptr() [with T = Nil]
../boost_1_36_0/boost/shared_ptr.hpp:165: note:                 boost::shared_ptr<Nil>::shared_ptr(const boost::shared_ptr<Nil>&)

왜 그럴까요 ? shared_ptr 선언을 보면 분명 template<class Y> explicit shared_ptr(Y * p); 이런 생성자가 있기 때문에 boost::shared_ptr<Nil> p1(np); 라고 한 부분은 에러 없이 잘 넘어갔습니다. 그런데, 왜 boost::shared_ptr<Nil> p2(0); 는 컴파일되지 않는 걸까요 ? 0이 상황에 따라 임의의 포인터로 해석된다면 당연히 Y* 로도 해석될 수 있기 때문에 shared_ptr(Y*)가 매치되어야 맞을 것 같은데 말입니다. Nil* np = 0; 도 잘 넘어가지 않았습니까 ?

그런데도 위와 같은 에러가 발생하는 이유는 뭔가 0을 해석하는 규칙이 상황에 따라 달라지면서 발생하는 문제로 보입니다. 위 코드에서는 파랗게 표시한 부분처럼 0을 int 로 해석하고 있어서 컴파일이 안되고 있습니다. 이런 문제를 피하려면 강제 형변환을 하는 수밖에 없습니다. 즉, 다음과 같이 고치는 거죠.

#include <boost/shared_ptr.hpp>

class Nil {
};

int
main()
{
  Nil* np = 0;
  boost::shared_ptr<Nil> p1(np);
  boost::shared_ptr<Nil> p2((Nil*)0);
}

그럼 아무 문제없이 잘 컴파일됩니다. ^^

0이 다양하게 해석됨으로 인해 발생하는 문제와 이를 해결하기 위한 C++0x의 해결책은 어떤 것인지도 다음글을 통해 알아두시면 좋을 것입니다.

C++0x(차기 C++ 표준) 미리보기 1, 널 포인터의 이름은 nullptr

제 글이 유익하셨다면 오른쪽 버튼을 눌러 제 블로그를 구독하세요. ->
블로그를 구독하는 방법을 잘 모르시는 분은 2. RSS 활용을 클릭하세요.
RSS에 대해 잘 모르시는 분은 1. RSS란 무엇인가를 클릭하세요.