표준안을 지키잣!

이전까지 쓰던 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는 별 코드에 다 집어넣고 요상한 알고리즘과도 빙빙 돌려제끼는 반복자인데… 이번이 처음이었습니다.. 이럴줄은.. ;ㅁ;

어머나. 소스코드를 복사하다니! 다음 vs. 네이버

뒷북을 울려라~ 이히~ 둥둥둥~

하드코어모드로 끝간데 없이 달리는 회사일정에 때맞추어 열린 World of warcraft: Burning Crusade의 흥미진진한 새로운 세상에다가 활동을 재개한 밴드일정으로 정신이 하나도 없는 까막군에게 심심함을 덜어주는 포스팅거리가 생겼으니 뒷북을 울려라~!

사건의 요지는 다음에서 만든 자바스크립트 소스를 네이버에서 홀랑 베껴다 써먹었다는 훈훈한 이야기입니다. 출처는 스마트플레이스. 덕분에 읽을만한 블로그를 찾았군요. (처음에 어디서 봤는지는 기억이 -_- ZDNet이었나..)

여하튼, C++을 이용해 패키지를 만드는 업체에 근무하는 저로서는 상상하기 힘든 일입니다. 저희팀에선 External Copy & Paste가 드물거든요. (회사 내부코드에선 간간히 있지만..)

일단은 스펙(프로토콜 문서 혹은 인코딩 문서)이 공개되어있는 경우에는 스펙보고 코드를 만들면 그만이고, 스펙이 안나와있으면, 코드도 없기 마련인지라.. 하핫. 외부 코드를 가져와서 사용할때는 라이센스를 면밀히 살피죠. 나중에 문제될까봐. (그래서 남은건 boost, ACE, STLPort 정도이군요..)

심지어는 C++ 개발자들이 많이 보는 Code Guru같은 사이트에 올라온 코드들도 무용지물인 경우가 많습니다. MFC를 배제하는게 기본 원칙인데 MFC코드가 많거든요. MFC코드를 배제하더라도 네이밍규칙같은 것에 위배되는게 많아서 고쳐쓰려면 결국 코드를 다시 작성하는거나 다름 없답니다. (고쳐쓰느니 그냥 짜고 말죠.) 그리고, 이해하지 못하면 유지보수가 불가능한데 이해를 하다보면 그냥 짜는게 깔끔한 코드를 만드는 지름길인지라..

서비스를 만드는 환경과 패키지를 만드는 환경의 차이일까요?

어느쪽이나 시간압박은 비슷하고, 주어지는 외부 압력도 유사합니다. (큰 차이는 모르겠군요.) 아마 개발자 자신의 자세가 문제였을거란 생각이 드네요. 소프트웨어 프로그래밍을 예술로 생각하고, 장인정신이 없는 코딩은 스스로 만족하지 못해 몸을 빌빌 꼬는 제 입장에서 볼 때 말입니다. (모로가도 돌아가기만 하면 된다. 오픈만 빨리하면 된다. 라고 생각하시는 일부 혹은 대다수의 어떤분들과는 매우 사이가 안좋아질 가능성이 농후한거죠.)

자신의 코드에 애착을 갖고, 자신의 작업 결과물에 자부심을 느끼며, 그 성과물로 인정을 받는 정직한 소프트웨어 엔지니어가 많아지기를 기도하며, 뒷북울리기를 그만 할랍니다. (5분 쉬었으니 이제 다시 일하러.. ;ㅁ;)

ps. clearable_pool이라는 쓸만한 템플릿을 완성한지라 조만간 포스팅할지도 모르겠습니다아.

ps2. 아 편집하다 날아간 내용이 있어서.. Daum과 Naver양사 모두 CCL을 위반한 케이스가 됩니다만(문제의 라이브러리), 문제가 되는 flexInput은 Naver가 Daum코드를 가져다 쓴게 맞는듯 합니다. 냐앙.