표준안을 지키잣!

이전까지 쓰던 STLPort는 5.0.1이었습니다. 뭐 큰 문제도 없고 해서 그냥그냥 쓰고 있었는데, 5.1.0이 나온걸 보고 업그레이드를 결심. 다운로드후 컴파일하고 프로젝트의 세팅을 전부 변경한 뒤에, 빌드를 시작했지요. (시켜놓고 회식갔다가 오늘 아침에 봤습니다.)

빌드에 오류가 났습니다. 흐음. 5.0.1에서는 오류가 없었는데, 5.1.0에서는 오류가 발생하는군요. 이럴땐, STLPort가 문제일 가능성이 크다고 판단, 오류로그를 뒤지기 시작했습니다.

stlport/stl/_algo.c(130) 에서 오류가 발생하는군요. 에러내역은 다음과 같습니다.

error C2512: ‘SCT::stdex::view_iterator‘ : 사용할 수 있는 적절한 기본 생성자가 없습니다.

SCT::stdex::view_iterator는 제가 만들어서 쓰고있는 커스텀 반복자인데요. 이게 ParentView에 있는 데이터를 순차적으로 접근하기 위한 녀석이라, 기본 생성자를 만들어 두고 있지 않습니다. 그래서, 에러가 난듯 하다고 판단. STLPort의 소스코드를 뒤져보기 시작했습니다.

STLPort 5.0.1의 소스코드

template <class _ForwardIter1, class _ForwardIter2>
_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
                     _ForwardIter2 __first2, _ForwardIter2 __last2) {
(.... 생략 ....)
  // 다른 부분!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  _ForwardIter1 __current = __first1;

  while (__first1 != __last1) {
    __first1 = find(__first1, __last1, *__first2);
    if (__first1 == __last1)
      return __last1;

    _ForwardIter2 __p = __p1;
    __current = __first1;
    if (++__current == __last1)
      return __last1;
(.... 생략 ....)
}

STLPort 5.1.0의 소스코드

template <class _ForwardIter1, class _ForwardIter2>
_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
                     _ForwardIter2 __first2, _ForwardIter2 __last2) {
(.... 생략 ....)
  // 다른 부분!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  _ForwardIter1 __current;// = __first1;

  while (__first1 != __last1) {
    __first1 = find(__first1, __last1, *__first2);
    if (__first1 == __last1)
      return __last1;

    _ForwardIter2 __p = __p1;
    __current = __first1;
    if (++__current == __last1)
      return __last1;
(.... 생략 ....)
}

STLPort 5.1.0

거의 같고 딱 1부분이 다른거 같습니다. 5.0.1은 __current에 __first1을 대입 하고있고, 5.1.0은 대입 하고있지 않습니다. (그것도 주석처리 되어있지요.)

이유는 28번 라인에서 언제나 __current는 __first1으로 업데이트가 되기때문에, 굳이 처음 생성시 __current에 __first1을 대입시켜줄 필요가 없지요. 이런 이유로 불필요한 작동을 줄이고자 주석처리를 해둔 것이라고 생각됩니다.

view_iterator에는 기본 생성자에 만들어줘야하는지, STLPort 코드를 수정해야할지를 고민하다가, C++표준안(정확히는 97년에 나온 드래프트)을 뒤적거려보니 Forward Iterator는 예측 불가능한 값을 갖는 Iterator를 생성하는 기본 생성자를 갖고 있어야 한답니다. view_iterator는 Random Access Iterator이고, Forward Iterator의 특성을 물려받으므로, 기본 생성자가 있어야 하는군요. 그래서 추가해줬습니다. (그리고, 배를 쨌습니다. 이상한 값을 갖는게 맞다잖아요. 무슨 결과가 나오든 전 모름 @_@)

당황해서 시간을 좀 낭비했는데… 역시 표준안을 숙지하고 미리미리 지켜주는게 인생 편하게 코딩하는 방법인가 봅니다. 에헤.

ps. view_iterator는 별 코드에 다 집어넣고 요상한 알고리즘과도 빙빙 돌려제끼는 반복자인데… 이번이 처음이었습니다.. 이럴줄은.. ;ㅁ;

글쓴이: crowmania

Chief Developer in Somansa Guitar/Vocal in Tonics Member of Justice Party

“표준안을 지키잣!”의 2개의 생각

  1. C++03 에도 기본 생성자는 singular 값을 가지고 non-singular값을 대입하는 것 외의 결과는 모두 undefined라고 되어 있습니다.

    하지만 container가 없는 경우, 그래서 begin(), end()가 없는 경우에는 기본 생성자가 end() (end of sequence) 값을 가지도록 해야 합니다. 예를 들어 std::istream_iterator같이 말이죠.

    copy(istream_iterator(cin), istream_iterator(), …);

    그리고 stlport에서는 표준을 지키지 않는 코드에 에러를 만들어주기 위해 = __first1을 뺀것 같은데요? ^O^

  2. C++ 표준안 문서를 구매해야겠다는 생각이 드는 요즘입니다. 후후.

    C++관련해서 제일 무서운 말은.. undefined… ㅋ

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다