time-to-market pressure in software development

Slashdot 글한 comment에서 인용.

It is rather amazing that there appears to be a consensus among industry experts that there has not been any improvement in code quality over the past 30 years or so despite the development of a vast number of new tools and languages. It is true that the size and scope of the average application has grown by leaps and bounds. But most likely, the primary contributing factor to these kind of quality problems is the prevalent time-to-market pressure in the software industry which is typically coupled with severe underestimation of time and resources required for projects.

time-to-market pressure in software development 더 읽기"

Refactoring traditional web application with MVC pattern (Part 2)

Adding functionality

Part 1에서는 Subscription을 등록하는 기능만을 구현했지만, Subscription을 삭제하고, 등록된 Subscription과 그 리스트를 보여주는 기능을 추가해보자.

case-when 절에 각각의 리퀘스트에 해당하는 처리 루틴을 추가하고, Subscription 클래스의 메서드를 호출하도록 구현한다.

Adding functionality (controller routines)

Subscription 클래스는 다음과 같이 구현할 수 있다.

Adding functionality (Subscription class)

Seperating View and Controller

Subscription 리스트를 보여주는 부분을 구현해보자.

code fragment that shows subscription list

문제는 Subscription 리스트를 보여주는 html code는 request 변수들을 처리하고 Subscription 클래스를 다루는 code 보다 자주 바뀔 가능성이 있다는 것이다. 물론, 이런 작은 예제를 구현할 때는 그렇지 않다. 웹 어플리케이션이 커질 수록 html code의 복잡도도 커지고, 그런 code를 다루는 것은 프로그래머가 아닌 디자이너의 역할로 넘어가는 경향이 있다. 따라서, 웹 어플리케이션의 규모가 커지면 View와 Controller의 구분이 불가피해지는 것이다. Subscription List를 보여주는 부분을 SubscriptionListView 클래스로 분리해보자.

code fragment that shows subscription list

Controller에서 직접 HTML을 rendering하는 코드를 SubscriptionListView를 사용하도록 변경해준다.

code fragment that shows subscription list

Refactoring traditional web application with MVC pattern (Part 2) 더 읽기"

우주 전쟁 War of the Worlds (2005)

소설 원작의 영화화

아마, 순전히 어린이용으로 쓰여진 것 외에 내가 처음으로 읽은 SF가 바로 우주 전쟁일 것이다. 아마 어린이용 전집의 첫번째 권이었던 걸로 기억한다. 초등학교 시절에 접한(그랬다고 기억하고 있는) 유일한 SF였던 것 같고, 꽤나 좋아해서 방학 때마다 읽었던 것 같다. 그리고, 이 소설에 등장하는 문어 모양의 거대한 기계는 내 꿈의 주요 소재였다. 그 기계가 서치라이트를 이리 저리 밝히고, 굉음을 내고 걸어다니는 동안, 나는 다리 밑에 숨어있는 내용의 꿈. 난 그 꿈을 자주 꾸었고 즐겼었다. 지금과 같이 극장의 스크린이 나를 대신하여 꿈을 꾸어줄 수 없었던 시절에 말이다.

Half-Life 2가 출시되기 전에 그것에 열광했던 이유 중에 하나는 아무래도 인간 저항군을 학살하는 삼발이 기계와 싸울 수 있다는 것 – 내 꿈을 직접 체험할 수 있다는 것이었다. 영화에서 등장한 삼발이(Tripod)는 물론 소설의 표지에 나왔단 거랑 모양이 너무 달랐고 두려움의 정도는 기대보다는 덜한 정도였다. 하지만, 삼발이 앞에서의 무력함은 똑같았다. 부두 하역 노동자에 불과한 평범한 소시민이 할 수 있는 일이란 그저 자신과 자신의 딸 정도를 보호하는 일이었다. 그 무력함의 쾌감이란. (그런 면에서 삼발이 파괴 장면은 오버.)

허무한 결말?

초등학교 이후로는 우주 전쟁을 읽을 일이 없었지만, 내용은 똑똑히 기억하고 있었다. 결말도 이미 알고있던 터라 내겐 이미 반전도 아니었고, 다코타 패닝양이 처음에 아버지랑 대화하면서 복선을 깔아주는 것도 즐길 수 있었다. 사람들의 결말 논쟁을 보면 대체로 원작에서도 그랬으니 별 문제 없다와 원작과 상관없이 너무 허무하다로 나뉘어진다. SF의 특성인지는 모르겠으나 이런 종류의 결말은 흔하다. 뭔가를 더이상 제어할 수 없어지게 되고, 그것을 극복하거나 말거나 이고. 그 극복은 인간의 능력보다는 우연성이 개입할 때가 있다. 물론 우연이라고 해도 충분한 개연성을 확보하고 있다는 것이 또 SF의 특성이지만. 영화를 볼 때가 아니라, 원작을 볼 때도 결말에 별다른 이의를 느끼지는 않았던 것 같다.

스필버그

스필버그의 공식은 간단해서 좋다. 해체된 가족의 회복. 회복하고 나서는 상처도 없이 말끔하다. 일종의 판타지. 판타지 속의 판타지라.

이미지

수많은 삼발이가 인간을 학살하는 장면과 삼발이가 콘크리트 건물 사이로 무너지는 광경은 꽤 멋있었다. 피바다도 괜찮았고. 그런 이미지들을 감상하기 위해서 한번 더 보고싶다.

우주 전쟁 War of the Worlds (2005) 더 읽기"

배트맨 비긴즈 Batman Begins (2005)

영웅의 성장기

스파이더맨처럼 배트맨 비긴즈도 영웅의 성장기를 그린 영화다. 스파이더맨은 영화 내에서 힘을 가지고도 개인적인 목적으로만 사용하는 성격(A)으로부터 그 힘을 공공을 위해 봉사하는 성격(B)으로 변화한다. 무려 여자친구도 버리고 말이다. 할아버지의 죽음이라는 사건을 통한 이러한 성격의 변화가 바로 스파이더맨에 나타나는 성장 플롯의 일부다. 스파이더맨 복장이나 여자친구와의 관계같은 부수적인 변화는 아무래도 좋다. 정신적인 면에서의 성장은 A->B의 간단한 구조를 가지고 있다. 사실, 사람들은 성장 플롯을 그다지 좋아하지 않았다. 영웅들의 본 스토리는 아무래도 선악의 대결 구도이지 않는가. 사실, 스파이더맨의 성공은 이런 선악 대결 구도에 지루해하기 시작한 관객의 요구를 반영한 것이라고 봐도 될 것 같다. 그런데, 배트맨 비긴즈도 스파이더맨을 본받아 성장 얘기를 하고 싶었나보다. 그런데 문제는 배트맨 비긴즈가 좀 멀리 갔다는 것이다.

가만히 생각해보자. 어린 배트맨 – 브루스 웨인은 부모님의 피살 당시 무력함에 죄의식을 가진다(A). 청년 브루스 웨인은 모든 범죄자에 대한 복수심에 불타고 복수를 시도한다(B). 고담 시티의 갱 두목 팔코니를 찾아갔다가 ‘넌 우리 세계를 몰라’하고 핀잔을 받은 웨인은 범죄자 집단으로 숨어들어서 그들의 생리를 배운다(C). 듀커드(리암 니슨)와 라스 알굴을 만난 웨인은 무술과 함께 범죄자에 대한 그들의 생각 또한 전수받는다(D). (듀커드의 대사를 듣고 이것들이 이제 대놓고 맛가는구나하고 생각했었다. 헐리우드의 기본 사상을 잠시 망각했었던 것.) 하지만, 웨인은 무술들만 쏙 배우고 나서는 그들의 생각을 거부하고 고담시티를 구하기 위한 영웅으로 귀환한다(E). 이 후는? 스파이더맨과 똑같다.

배트맨의 성격은 A->B->C->D->E의 복잡한 변화를 거친다. 상당히 복잡한 캐릭터다. 배트맨 비긴즈가 다른 영웅 성장기와 다른 점은 바로 이것이다. 이 영화를 보고나서 과연 이 영화가 흥행할 수 있을까 의문을 가졌을 정도니까. 이유는? 물론 관객들은 복잡한 걸 싫어하니까. 이런 영화가 나온다는 사실 자체가 관객들의 수준이 좀 높아졌다는 걸 의미하는걸까? 아니면 제작사를 설득할 수 있는 크리스토퍼 놀란 감독의 역량인가?

배트맨은 아메리칸 닌자

역시 미국인들에게 ‘동양’의 국적은 죄다 일본인가보다. 티벳 고원(?)을 배경으로한 닌자 훈련이라. 원래부터 배트맨은 표창과 줄타기 등의 닌자 기술을 사용하는 영웅이긴 하다. 라스 알굴 일당이 국제 조직이다보니 무술이나 언어, 본거지도 국제화되어 있다고 억지로 봐주는 것도 가능하긴 할 것 같다.

리암 니슨이 듀커드로 나올 때는 “음, 제다이 마스터가 여기에. 그럼 배트맨은 마스터를 배신하고 다크 사이드에 넘어간 파다완?”이라고 생각했다. 제다이도 역시 사무라이와 도제 제도를 기반으로 하고 있다는 사실을 생각하면, 리암 니슨을 배트맨의 스승으로 캐스팅한 것은 묘한 어울림이 있다.

크리스찬 베일

크리스찬 베일은 역대 배트맨 중 가장 예쁜 배트맨이다. 여피의 이미지가 재산가 브루스 웨인이랑도 잘 어울리는 것 같고, 수없이 갈등을 하는 캐릭터에도 예쁜 남자가 어울린다. (예쁜 것에 모든 합리화의 초점을.) 처음으로 크리스찬 베일을 영화를 통해서 본 것은 아메리칸 싸이코였다. 손도끼를 든 여피족. 섹스를 하는 자신의 몸을 거울을 통해 들여다보는 그의 모습을 아직도 잊을 수가 없다. 이퀄리브리움은 개인적으로 좀 별로였고. 머시니스트도 괜찮다고 하던데 기회가 된다면 보고 싶다.

배트맨 비긴즈 Batman Begins (2005) 더 읽기"

부동소수점 수의 비교

얼마전에 재민군이 질문했던 내용인데, 태준형의 도움으로 해결했던 문제입니다.

Question

먼저 다음과 같은 코드가 있습니다.

#include 
int main()
{
int i = 10;
double val = i*12.34;
if(val == i * 12.34){
printf("Equaln");
} else {
printf("Not Equaln");
}
}

결과는 무엇일까요?

물론 답은 이 프로그램을 컴파일하고 실행하는 환경에 따라 다르다입니다. 즉, 어셈블리 코드를 생성하는 컴파일러와 이 코드를 실행하는 아키텍쳐에 따라 다를 것이라고 예상할 수 있습니다. 그런데, 신기한 것은 같은 아키텍쳐(Pentium 3)와 같은 컴파일러(gcc 3.4)를 사용하더라도 OS에 따라(Linux와 FreeBSD) 다른 결과가 나온다는 것입니다. 자세히 얘기하면, Linux에서는 “Not Equal”이 출력되고, FreeBSD에서는 “Equal”이 출력됩니다. 어째서 그럴까요?

Answer

설마, 어셈블리 코드가 다르게 나오는 걸까요? OS가 달라서 그럴지도, 컴파일러 설정이 달라서 그럴지도 모르지 않습니까? 아니면 컴파일러 버그? 그런데, 그렇지 않습니다. 부동소수점 연산과 비교를 수행하는 부분의 코드는 다음과 같이 똑같습니다.

movl    $10, -4(%ebp)
fildl   -4(%ebp)
fldl    .LC0
fmulp   %st, %st(1)
fstpl   -16(%ebp)
fildl   -4(%ebp)
fldl    .LC0
fmulp   %st, %st(1)
fldl    -16(%ebp)
fxch    %st(1)
fucompp
fnstsw  %ax
andb    $69, %ah
cmpb    $64, %ah
je  .L3
jmp .L2

간단히 설명하면, 10과 12.34를 FPU stack에 넣고 곱셈을 수행한 후, (FPU stack에 들어있는) 결과를 다시 메모리에 저장합니다. 두번째 연산을 위해 역시 10과 12.34를 FPU stack에 넣고 곱셈을 수행한 후, 메모리에 저장했던 결과도 다시 FPU stack에 불러들여, 두 값의 비교를 수행하는 코드입니다.

두 값의 차이는 곱셈의 결과가 메모리로 잠시 다녀왔는가의 여부 뿐이죠. OS에 따른 결과의 차이도 바로 여기서 발생합니다.

The difference between Linux and FreeBSD is that in Linux, the FPU is operated by default in “extended precision” mode, where 80-bit internal registers are used for floating point numbers. In FreeBSD, the default is to use “double precision” mode, where 64-bit precision is retained.

Excerpt from Resolution of Differences Between X86 Linux/glibc Floating-Point to Integer Conversion Behavior Relative to Other Platforms

즉, 387 내에서 부동소수점 수는 80bit의 정밀도를 가질 수 있는데, 메모리 상에서는 IEEE 754대로 64bit의 정밀도를 가지므로 일종의 rounding error가 일어난다는 거죠. 그리고 FreeBSD에서는 80bit 정밀도 기능을 OS 수준에서 꺼버리지만 Linux는 그렇지 않기 때문에 차이가 나는 것이구요.

More Fun?

참고로, 제 amd64 머신에서는 “Equal”이 출력되고 다음과 같은 코드를 생성합니다.

movl    $10, -4(%rbp)
cvtsi2sd    -4(%rbp), %xmm1
movlpd  .LC0(%rip), %xmm0
mulsd   %xmm1, %xmm0
movsd   %xmm0, -16(%rbp)
cvtsi2sd    -4(%rbp), %xmm1
movlpd  .LC0(%rip), %xmm0
mulsd   %xmm0, %xmm1
movlpd  -16(%rbp), %xmm0
ucomisd %xmm0, %xmm1
jp  .L5
je  .L3

즉, SSE instruction을 사용하죠. gcc는 x86-64 (aka. amd64) 아키텍쳐에서는 기본적으로 SSE를 사용한다고 합니다.

sse Use scalar floating point instructions present in the SSE
instruction set. This instruction set is supported by Pentium3
and newer chips, in the AMD line by Athlon-4, Athlon-xp and
Athlon-mp chips. The earlier version of SSE instruction set
supports only single precision arithmetics, thus the double and
extended precision arithmetics is still done using 387. Later
version, present only in Pentium4 and the future AMD x86-64
chips supports double precision arithmetics too.
For i387 you need to use -march=cpu-type, -msse or -msse2
switches to enable SSE extensions and make this option effec-
tive. For x86-64 compiler, these extensions are enabled by
default.
The resulting code should be considerably faster in the major-
ity of cases and avoid the numerical instability problems of
387 code
, but may break some existing code that expects tempo-
raries to be 80bit.
This is the default choice for the x86-64 compiler.

Pentium 4이상의 머신에서 다음과 같이 컴파일 하면 역시 “Equal”이 출력되는 것을 확인할 수 있습니다. (Pentium 3에서도 컴파일은 되지만, Illegal Instruction 예외가 발생합니다.)

gcc -msse -msse2 -mfpmath=sse test_double.c

Conclusion

문제의 원인은 x86 FPU가 80bit extension을 사용하고 있고, FreeBSD에서는 이 기능을 꺼버리고 Linux는 그대로 두는 것에 있습니다.

어떻게 보면, x86의 FPU가 사용하는 80bit extension이 표준(IEEE754)을 잘 지키지 않은 것이 문제라거나 Linux가 문제의 소지가 있는 CPU 기능을 켜놓은 것이 문제라고 볼 수도 있습니다. 하지만, 모두들 아시다시피 부동소수점 수의 비교 연산은 보장받기 어려운 것이므로, 이런 간단한 비교 연산의 정확도를 버리고 연산의 정밀도를 택한 trade-off는 정당하다고도 생각됩니다.

결국, 부동소수점 수의 비교 연산은 아무리 간단하더라도 rounding error와 같은 문제를 무시해서는 안된다는 것이죠.

위에서 인용했던 글에서 읽어보라고 하고 있는 David Goldberg의 What Every Computer Scientist Should Know About Floating-Point Arithmetic를 읽어볼 생각입니다.

부동소수점 수의 비교 더 읽기"

첫눈 – 첫 인상

첫눈 베타 서비스시작되었군요.

1noon

첫눈을 사용할 때 가장 먼저 눈에 띄는 점이라면 아무래도 구글 스타일의 최소주의 인터페이스와 구글 서제스트와 같은 기능입니다. 국내에서는 어떤 메이저 검색 서비스도 구글 인터페이스를 사용하지 못했다는 점에서 첫눈의 이런 인터페이스는 흥미롭습니다. 국내 사용자들도 이제 광고로 점철된 포탈 페이지로부터 벗어날 수 있을까요? 서제스트 기능은 네이버에서도 채용하고 있긴하지만, 불여우에서 제대로 동작하지 않습니다. 첫눈의 것은 불여우에서도 잘 동작합니다. 괜히 기분 좋네요.

1noon

검색 결과의 처리 방식은 사실 구글 스타일이라기 보다는 국내의 다른 검색 서비스들과 유사합니다. 중요한 사이트나 인기사이트를 맨 위에 올려주고, 뉴스를 그 다음에, 게시판이나 블로그 등의 웹 컨텐츠를 그 아래에 배치하는 식입니다. 흥미로운 것은 검색 결과를 주제별로 분류하는 기능입니다. 더 많이 써봐야 알겠지만, 언뜻 봐서는 상당히 잘 동작하는 것 같습니다. 루나님에 의하면 비비시모라는 해외의 검색 서비스에서 시도하고 있는 것이라고 하는군요. 검색 결과를 처리하는 이러한 두가지 방식은 구글의 방식과는 어느 정도 차이가 있습니다. 그 차이는 검색 결과의 중요도나 내용을 구분해주려는 시도가 사용자에게 얼마나 의미가 있는가하는 의문에 대한 대답일 것입니다. 구글처럼 순서대로 보여주는 것 이상으로 말이죠.

1noon

1noon

검색 결과는 아직(?) 국내에 한정되어 있는 것 같습니다. 지금은 예고편 #1에 불과하니 벌써 실망할 필요는 없으리라고 생각합니다.

광고는 아직(?) 전혀 없습니다. 첫눈의 수익 모델은 아직은 노출이 안된 것 같군요. 아무래도 검색 위주의 서비스에서 가장 궁금하고 기대되는 것은 수익모델입니다.

첫눈 서비스보다 더욱 흥미로운 것은 첫눈의 철학입니다.

"좋은 인재들이 즐겁게 일하기"라는 얘기는 누구나 어떤 회사에서도 할 수 있고 또 하는 얘기입니다만, 정말로 실천되고 있느냐는 별개의 문제입니다. 구글은 그것을 정말로 실천함으로써 유명해진 케이스죠. "검색에 집중"은 정말 어려운 문제라고 생각합니다. 지금까지 국내에 순수한 검색 서비스는 없었다는 점이 그것을 말해줍니다. 역시, 구글은 이것을 해냈기 때문에 유명해진 것입니다. 첫눈은 과연 어떨까요?

첫눈은 사용자에게 주는 새로운 가치를 의미한다고 합니다. 첫눈이 정말로 새로운 가치를 창출하는가는 역시 사용자에게 달려있고, 앞으로 지켜볼 수 밖에 없을 것 같습니다. 첫눈 예고편 #1이 구글처럼 위대한 서비스의 첫 발자욱으로 기억되는 날을 기대해봅니다.

첫눈 – 첫 인상 더 읽기"

연애의 목적 (2005)

연애의 목적

연애의 목적은? 신문 가판대를 지나치며 보듯 인터넷에서 슬쩍 컨닝한 정답은, 연애의 목적이란 것은 바로 연애다. 하지만, 작가나 감독의 의도가 어쨌든 간에 나로서는 영화만 보고서 연애의 목적이 무엇인지 잘 파악이 되질 않는다. 그저 유림(박해일)과 홍(강혜정)의 캐릭터를 즐기는 것만으로도 충분히 즐거웠기 때문일런지도 모르겠다. 불성실한 관객이랄까. 유물론자인 내가 생각하는 연애의 목적이란 연애에 참여하는 인간들이 서로에게서 얻을 수 있는 이익 때문이다. 물론 그 이익이란 당사자들에 따라 다르기 마련이다. 사회적/정서적/경제적/성적 이익 무엇이든 될 수 있고, 또 여러가지가 될 수도 있다. (결혼에 관한 나의 글을 참고해보라.) 연애의 목적이 연애란 것도 선천적으로 또는 구조적으로 연애를 할 수 밖에 없다는 것이고, 그것은 선천적/구조적 경향을 유도한 원인이 되는 어떤 이익으로 환원해서 생각할 수 있지 않을까.

솔직함 vs. 의뭉스러움

유림이라는 캐릭터의 최대 매력은 아무래도 섹스라는 연애의 목적을 처음부터 솔직하게 털어놓는 것이다. 한 10년 전쯤에 비해서야 지금은 훨씬 나아졌지만, 아직도 섹스라는 단어를 꺼림찍해하는 사람들이 많은 현실에서, 유림은 뭔가 달라도 다르다. 유림이 솔직함의 극단이라면, 홍은 그 반대다. 홍은 계속 유림의 요구를 거절하면서도 슬쩍슬쩍 들어주는 의뭉스러움을 보여준다. 직접적인 표현은 마지막 그 순간까지 미룬다.

개인적인 견해로는 가장 이상적인 연애의 관계가 이런 관계가 아닐까 싶다. 솔직한 두 사람의 연애는 쉽게 지루해지기 마련이고, 의뭉스러운 두 사람의 연애는 아예 제대로 시작하기도 힘들지 않을까. 솔직함 또는 의뭉스러움만으로 연애라는 관계가 지속되기는 힘들다. 기본적으로 연애는 신뢰게임이다. 연애가 지속되어서 서로 신뢰하는 관계가 된다면? 왜, 그래서 사랑의 무덤이 바로 결혼이 아니겠는가.

여자의 "No"는 "Yes"?

요즘 세상에 좀 아는 체 하는 인간들에게 이런 얘길 하면 정치적으로 올바르지 못하다는 핀잔을 받게 마련이겠지만, 이 영화는 당당하게 그렇게 얘기하고 있는 것 같다. 정녕 남성들의 판타지가 아니었단 말인가. 남성 감독의 필터링을 당하긴 했지만, 여성 작가의 작품이란 점에서 그렇게 보기는 좀 힘들 것 같다. 내가 아는 한 연애에 가장 능통한 친구 녀석이 항상 하는 말이 있다. 연애는 항상 "case-by-case"라고. 마음에 드는 남정네가 여관가자고 하면 여자의 No도 Yes가 될 수 있는 것이다. 눈 맞으면 뭔 짓을 못하겠는가.

솔직히 수학여행 때 섹스 장면은 멋도 모르는 관객이 보기엔 완전히 강간이었다. 단, 이어지는 홍의 친절한 고백이 없었다면 말이다. 물론, 유림은 분명히 홍이 자신에게 넘어왔다는 것을 어떤 감각으로 느꼈을 것이다. 관객은 다만 감독에 의해서 그러한 감각이 차단당했을 뿐. 아니면, 감독에 비해 관객들이 둔감한거라거나.

복수는 나의 것, 새로운 희망

연애의 목적은 그 관계가 주는 이익을 기반으로 하고 있기 때문에, 그 이익의 경쟁력이 사라지면 바로 그 관계는 파국으로 치달을 수밖에 없다. 홍은 그러한 케이스의 전형적인 희생자였고, 영화의 시간대에서는 다시 유림이 그 희생자가 된다. 신기하게도 남자가 그런 순애보의 희생물이 되는 상황이 미디어를 통해 비춰지는 것이 내게는 상당히 낯설다는 것을 느꼈다. 그동안 순애보의 희생물로 당해온 여자들의 복수극이라고 보면 오버일까. 두차례의 복수극이 휩쓸고 지나간 자리에서, 그리고 이제는 달라진 두 사람의 관계 위에서, 연애는 다시 시작된다.

연애의 목적 (2005) 더 읽기"

g++ 3.4 bug: protected member of template base class hidden from template child class

g++ 3.4도 아직 그다지 안정화 되어 있는 상태는 아닌 모양이다. 이 버그의 workaround 중 하난 멤버에 접근할 때 this->를 사용하는 것이다. 자세한 내용은 다음 링크를 참조.

http://lists.debian.org/debian-gcc/2004/05/msg00293.html

g++ 3.4 bug: protected member of template base class hidden from template child class 더 읽기"

g++ 2.95 bug: internal compiler error when accessing template member function from member function

Description

어떤 멤버 함수로부터 같은 클래스의 템플릿 멤버 함수에 접근할 경우, gcc 2.95가 internal compiler error를 발생시킴.

Example

GCC 2.95 template bug

Workaround

템플릿 멤버 함수 (bar)를 멤버 함수(foo)보다 위쪽에 정의해주면 됩니다. 이 외에도 gcc 2.95는 template 관련 버그가 꽤 많죠. template을 많이 사용한다면 부득이 하지 않은 이상 3.x 이상을 사용할 것을 권장합니다.

g++ 2.95 bug: internal compiler error when accessing template member function from member function 더 읽기"