« Previous : 1 : ... 197 : 198 : 199 : 200 : 201 : 202 : 203 : 204 : 205 : ... 221 : Next »

<날개셋> 편집기를 오래 써 온 분들은 아마 아실 겁니다. 찾기/바꾸기 대화상자에 아주 교묘한 버그가 있습니다.
글을 쓰다가 Ctrl+F 또는 Ctrl+H로 이 대화상자를 한 수십 번 꺼내다 보면
정말 가끔, 아주 random한 확률로 엉뚱하게 explorer.exe가 죽거나, 편집기 프로그램이 죽거나 응답 불능 상태에 빠집니다. 윈도우 XP부터 비스타에서 모두 이런 증상이 나타나는 걸 확인했습니다. 에러 대화상자를 살펴보면 comctl32.dll이 뻗었다고 나옵니다.

이건 저도 원인을 알 수 없고 참 괴이하기 그지없는 버그입니다.
딱 원하는 때에 맞춰 재연은 절대로 할 수 없지만, 그래도 어디서나 언젠가는 100% 반드시 나타난다고 보장할 수 있는 현상이었지요.
발생 조건에 관한 한 최악의 버그입니다. 저는 무려 <날개셋> 3.x 시절부터 이것에 대해 알고 있었지만 디버깅할 엄두를 못 내고 있었습니다.

찾기/바꾸기 대화상자가 <날개셋> 편집기의 여느 대화상자들과 다른 점은 '탭 컨트롤'을 써서 찾기와 바꾸기 기능을 구분하고 있다는 점입니다. 혹시 이게 문제인가 싶어서 이번 기회에 아예 대화상자의 디자인을 바꿔 버렸습니다. 물론 5.53에는 아직 이게 적용이 안 돼 있고요.
5.53 이후로 다음 버전이 언제 나오게 될지 모르겠지만, 이렇게 하니까 이제는 저 문제가 없어졌는지 최소 몇 달간 살펴볼 예정입니다.

Posted by 사무엘

2010/04/19 07:35 2010/04/19 07:35
Response
No Trackback , a comment
RSS :
http://moogi.new21.org/tc/rss/response/249

철도에 고속철이 있다면 여객 항공기에는 초음속기가 있습니다. (정말 적절한 비유 ㅋㅋㅋㅋ)

1.

1903년이던가, 미국의 라이트 형제가 최초로 동력으로 움직이는 항공기를 발명한 후,
항공기는 1차, 2차 세계대전을 거치면서 전투기로도 등장하고 이내 여객용으로 가히 지구촌 시대를 열었습니다.
우리가 이용하는 대부분의 여객기는 최고 속도 순항 상태일 때 시속 850~900km (마하 0.9)쯤 되는 아음속기입니다. 이 정도로도 육지에서는 도저히 경험할 수 없는 빠른 속도이며, 사실 바람을 잘 탈 때면 아음속기도 시속 1200~1300에 도달해서 잠시 초음속으로 날기도 합니다. 그러나 속도에 대한 열망은 그것으로 모자라 초음속기의 개발을 부채질했습니다.

물론 자동차 중에도 초음속 자동차라는 게 있어서 주로 사막에서 시범 운행한 경우가 있습니다.
하지만 실용성은 거의 없죠. 그리고 그런 차들은 엔진도 일반적인 자동차의 4행정 기관이 아니라 제트 엔진을 쓰기 때문에 배기가스 배출, 연료 소모도 장난이 아닙니다. 여객 항공기는 대개 터보 팬 엔진을 쓰죠.

철도를 움직이는 핵심 동력원으로는 지하철과 고속철 모두 전기가 각광을 받고 있지만 비행기의 동력원은 역시 기름입니다. 그렇다고 해서 디젤-전기 방식은 아니고요. 항공유는 경유-중유 수준의 묵직한 디젤유는 아니고 휘발유에서 등유 사이뻘 되는 등급으로 알고 있습니다. 단지, 경주용 자동차용 연료에다 그러는 것처럼 옥탄가를 더욱 강화하고, 특히 영하 수십 도에 달하는 구간에서도 얼지 않도록 부동액 성분도 첨가된다고 합니다.

오늘날 실용적으로 운행되는 고속철들이 최고 시속 250~300km대입니다. 하지만 비행기는 활주로를 한창 지나서 날아오르기 직전에 이미 시속 300km대로 달리게 됩니다. 열차가 자꾸 자주 정차하는 건 싫지만 항공기가 이착륙하는 건 신나고 재미있습니다.

항공기는 고도의 유체역학 원리에 따라서 하늘로 뜨게 됩니다. 당연한 말이지만, 양 옆으로 날개도 폼으로 있는 게 아니라 치밀한 설계에 의해 넣은 것이죠. 그런 비행기들은 지구와 같은 공기가 없는 곳에서는 연료를 연소시킬 수 없기 때문에 날 수 없기도 하지만, 양력을 발생시킬 수 없어서 더욱 뜰 수 없습니다.
또한 반대로 말하면 우주선들은 어차피 지구 대기권을 나는 항공기와는 다른 방식으로 운항하기 때문에 날개가 필요 없습니다.

2.

전투기야 우리나라도 초음속기 개발에 성공했으니 더 말이 필요없지만,
초음속 여객기 하면 역시 영국과 프랑스 합작으로 개발되었던 콩코드가 거의 유일합니다. 잘 알다시피 음속의 2배를 조금 넘겼지요.
사실, 콩코드가 등장하기 전에 미국과 소련은 냉전 구도 하에 우주 개발 경쟁만 한 게 아니라 초음속 여객기 연구도 앞장서서 했습니다. 하지만 미국은 그런 건 만들어 봐야 경제성이 없다는 판단 하에 일찌감치 연구를 포기했습니다. 그 대신 아음속 여객기의 덩치를 더욱 키우는 연구를 계속했죠.

그 반면 소련은 콩코드보다도 먼저 사실, 세계 최초의 초음속기를 만들어내기는 했지만 상용화하지는 못했습니다. 이런 와중에 영국과 프랑스가 유럽의 항공 기술의 자존심을 걸고 막대한 비용을 들여서 공동 연구를 한 끝에 콩코드를 만들어 내고, 적자까지 감수하면서 나름 20년이 넘는 세월 동안 운행을 한 것입니다. 대서양을 건너 런던· 파리에서 미국 뉴욕 사이를 왕래했습니다.

콩코드가 첫 비행에 성공한 것은 1969년 3월로, 인간이 최초로 달에 가는 데 성공한 아폴로 11호 발사의 4개월 남짓 전입니다.
콩코드는 빠른 속도를 내기 위해서 많은 것을 희생해야 했습니다.
폭이 작고 복도가 매우 좁아져서 한 줄당 좌석이 기차나 버스 수준인 2x2입니다. (우왕!)
만석일 때 100수십 명 남짓밖에 탈 수 없어서 이는 결국 한 사람당 매우 비싼 운임으로 연결됩니다. 2003년경에 대서양 한번 건너는 편도 운임이 한국 돈으로 거의 900만~1천만 원.. 일반 아음속 항공기 일반실 운임의 10배가 넘었다고 합니다.

어마어마한 동력을 내야 하기 때문에 같은 거리를 날아도 연료도 더 많이 들고, 이륙도 더 빨라야 하고 타이어에 걸리는 부담도 더 크고, 뜰 때 더 가파르게 하늘로 올라야 했다고 합니다. 거기에다 성층권의 오존층 파괴 문제, 소닉 붐 충격파, 자국 영공 내에서의 초음속 비행에 대한 규제 등, 골치 아픈 요인도 많았습니다.

끝으로 또 생각할 게 있습니다. 비행기가 하늘을 나는 상공은 영하 수십 도에 이르는 저온이지만, 그 정도로 빠르게 날면 공기와의 마찰 때문에 기체 역시 100~200도나 되는 온도로 달궈집니다. 우주선이 지구 대기권으로 재돌입할 때 시뻘겋게 열 받고 달아오르는 것과 같습니다. 그렇기 때문에 초음속기는 단순히 엔진의 출력만 강한 게 아니라 열에도 강해야 하고 마치 철도 레일이 여름에 늘어나는 것처럼 어느 정도 신축 현상에도 대비하여 설계되어야 합니다.

3.

그럼에도 불구하고 초음속 여객기의 위력은 정말 대단했습니다.
마하 2.2의 속도로 날면서 예전에 8시간 가까이 걸리던 런던-뉴욕을 고작 3시간 반대로 단축시켰기 때문입니다. 생긴 것도 학처럼 정말 우아하게 생겼죠.

이거 아십니까? 콩코드는 지구가 자전하면서 지표면이 돌아가는 속도보다도 더 빨리 이동하는 인류 최초의 교통수단이었습니다. (우주선이나 로켓은 아예 지구를 떠날 때 쓰는 물건이므로 논외로) 그래서 정오에 런던을 출발하면 현지 시각으로 오전 11시 30분에 뉴욕에 도착할 수 있었습니다.
이를 이용해 그때 인류 역사상 초유의 엽기적인 프로젝트가 진행되기도 했습니다.

1973년 6월 30일에 개기 일식이 일어날 때의 일이었습니다. 이런 사건은 지구상에서는 잘 해야 5~7분 남짓한 시간 동안밖에 관측할 수 없으며 사실 이것도 굉장히 운이 좋은 경우입니다. 그런데 지구의 자전 속도보다 더 빠른 비행기가 발명되었으니, 비행기로 달의 그림자를 쫓아가면서.. 일식 장면을 계속 관측하는 게 어떨까 하는 엉뚱한 생각!

과학자들은 일식을 가장 잘 볼 수 있는 경로를 치밀하게 계산해 놓은 후, 그 비싼 콩코드 비행기를 무려 전세 내서 기내에 온갖 측정 장비들을 설치했습니다. 덕분에 하늘에서 개기 일식을 무려 70분이 넘는 시간 동안 관측할 수 있었습니다. 그 해 10월 15일에 오일 쇼크가 터지기 100일 정도 전의 일이었죠.
http://sodyssey.egloos.com/2323422.

4.

그러나 초음속 여객기는 대중화하기에는 아직 시기상조였는지? 콩코드 역시 운영상의 어려움과 적자에 시달렸습니다. 자존심이 있는데 당장 운항을 중단할 수는 없고 좀 애물단지 계륵처럼 됐죠. 그렇게 시간은 흘러서 20세기가 막바지에 이르고 콩코드의 내구 연한 30년도 임박하기 시작했습니다.

그러던 차에 2000년 7월, 대형 사고가 터지고 말았습니다.
프랑스 파리의 드골 공항에서 이륙하던 콩코드 4590편.
이륙하는 과정에서, 직전 항공기가 이륙하면서 떨어뜨리고 간 금속띠를 밟으면서 타이어가 쫙~ 찢어져 터지고, 그 타이어 조각이 연료탱크를 파손했습니다.
비행기는 이미 시속 300km V1 속도를 넘어서서 이륙을 중단할 수 없는 상태가 돼 있었고, 기체 뒷부분이 불길에 휩싸인 채로 하늘로 떴습니다.

연료는 양 날개 내부에 담겨 있었는데 그게 다 홀랑 타 버리니 날개가 남아나질 못했죠. 곧바로 양력을 잃고 실속 상태. 조종이 불가능해진 비행기는 고도 100미터를 채 못 오르고 저공에서 빙빙 돌다가 추락해 버립니다.
화재 때문이었는지 탑승객 전원 사망.
최첨단 초음속기에다 25년 가까이 무사고를 자랑했던 호화 여객기 콩코드의 위상이 크게 흔들리게 되었습니다.
사고 원인을 추적한 과정이 정말 대단하더군요. 추리 소설을 읽는 기분이었습니다.
http://blog.naver.com/toysher?Redirect=Log&logNo=50007967386

이 사고를 계기로 콩코드는 안전 기준도 더욱 강화되었지만 슬슬 운행 중단으로 기울어 갔고,
2003년 10월엔 모든 콩코드기가 운항을 중단하고 현역에서 물러나게 됩니다.
간간히 뉴욕-도쿄 간 초음속기가 새로 개발 중이라고 몇 년 전부터 소식은 들어 왔지만 그게 언제 다시 실현될지는 모르겠습니다.

Posted by 사무엘

2010/04/16 12:35 2010/04/16 12:35
, , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/247

원에 대한 적분 외

원이란 2차원 공간상의 한 점에서 거리가 같은 점들의 집합으로 정의된다. 공간이 3차원으로 확장되면 구도 이와 같은 맥락으로 정의 가능하다.
이 정의에 따라, 먼저, 0..r 범위에서 반지름이 r인 사분원을 나타내는 방정식

  f(x) = sqrt(r^2 - x^2)

를 정의하자.
이 사분원의 호의 길이는 거리의 적분에 따라

  int(  sqrt( f'(x)^2 + 1 ) , x=0..r)

(f'(x)는 f(x)의 도함수. int는 짐작하듯이 0부터 r까지 x에 대한 정적분을 나타냄)
을 풀면 PI*r/2 가 된다. 사분원의 길이이므로 여기에다 4를 곱하면
반지름이 r인 원의 길이는 2*PI*r이 나온다.
위의 적분식에서 1은 당연한 말이지만 적분변수가 약분되어 1이 된 것이며, 그걸 역시 제곱한 값이기도 하다. 괜히 더해진 게 아니다. ^^;;

넓이는 그냥 f(x)를 적분하면 바로 구해진다.

  int( f(x), x=0..r)

의 값은 PI*r^2 /4 가 되고, 역시 4를 곱하면 반지름이 r인 원의 넓이는 PI*r^2이 된다. 적분을 실제로 풀기 위해서는 치환 적분 기법이 필요하다.

이제 3차원 세계로 가서 구의 부피를 구하면 어떨까?
반구의 단면은 역시 0부터 r까지 반지름 자체가 원의 방정식과 같은 무수한 원으로 이루어져 있으며 이것들을 적분하면 부피를 구할 수 있다. 어렵지 않다. 즉, 원의 넓이 PI*r^2에서 r 대신에 f(x)를 넣으면 된다는 소리.

  int( f(x)*f(x)*PI, x=0..r)

의 값은 2/3 * PI * r^3이 된다. 반구의 부피이므로 이것에다 2를 곱하면 4/3 * PI * r^3이 바로 반지름이 r인 구의 부피이다.

마지막으로 구의 겉넓이를 구해 보자.
여기서 사람들이 제일 많이 틀리는 게 뭐냐 하면, 넓이를 그대로 적분하면 부피가 되었듯이 원호 길이를 그대로 적분하면 겉넓이가 될 거라는 생각이다. 그런데 그렇게 하면 적분을 해석적으로 풀든, 심지어 100개 1000개로 구간을 아무리 많이 나눠서 컴퓨터로 계산을 해 봐도 정확한 값이 나오지 않는다! 실제값보다 더 작은 값이 나온다.

원의 넓이나 구의 부피처럼 각 구간에서의 함수값만이 중요하다면 구간 수를 무수히 늘림으로써 정확한 값으로 수렴이 가능하겠지만, 구의 겉넓이는 앞서 다뤘던 '길이'를 구하는 것과 일면 비슷한 개념이다. 내 자신의 값뿐만 아니라 인접한 구간과의 기울기라는 개념이 감안되어야만 정확한 적분값이 나온다.
그래서 2*PI*r뿐만 아니라 원호를 구할 때 쓰던 식이 첨가되어야 한다.

  int( 2*PI * f(x)* sqrt( f'(x)^2 + 1 ), x=0..r)

이 적분식의 값은 2*PI*r^2이 나오며, 역시 2를 곱하면 반지름이 r인 구의 겉넓이는 4*PI*r^2임을 알 수 있다.

덧붙이는 말

1. 1부터 100까지 일일이 덧셈을 할 필요가 없이 등차수열의 합을 구하는 식에 대입만 하면 100이 아니라 1000, 10000까지의 합도 손쉽게 구할 수 있듯.. 우리가 알고 있는 리만 적분도 굉장히 대단한 지식이다. 수천, 수만 개의 구간을 나눠서 일일이 함수값을 구하며 뺑이를 칠 필요 없이, 함수식의 부정적분을 구한 후 하한값과 상한값의 차이만 구하면 된다니, 놀랍지 않은가? 게다가 여기에다 부분 적분과 치환 적분의 위력까지 더해지면 초월 함수를 다루기도 더욱 수월해진다.

2. 사실 미분과 적분은 서로 다른 별개의 분야에서 출발했다. 접선 기울기하고 면적/부피는 언뜻 보기에 분야가 다른 것 같은데, 함수의 부정적분이 도함수의 역함수와 같다는 것이 증명되면서 미적분학이라는 한 학문이 태동한 것이다. 옛날엔 '극한이라는 걸 수학적으로 엄밀하게 정의하는 게 가능하나?' '이건 너무 사악한 사고방식이 아닌가?' 이런 걸 갖고 고민하던 시절이 있었다. 그저 기계적인 계산 테크닉(로피탈의 정리 같은. -_-)만 달달 외워서 점수 따기에는 이 분야는 너무나 깊이 생각하고 느껴야 할 게 많다. 본인 역시 학창 시절엔 그런 걸 별로 경험하지 못했다. 세상에 이런 개념을 처음 만든 사람은 무슨 생각으로 이런 걸 만들어냈을지를 곱씹어 보자.

3. 리만 제타 함수라는 게 있다. ζ(n)은 1/1^n + 1/2^n + 1/3^n ..... 의 극한이다. n=1인 경우에 속하는 조화 수열은 0에 수렴하지만, 그 합은 로그 스케일로 매우 느리게 발산-_-하긴 한다. (일반적으로 미분과 적분을 거치면 x의 지수가 1 늘어나거나 줄게 마련인데, 지수가 -1에 속하는 1/x은 부정적분이 예외적으로 생뚱맞은 ln x로.. =_=) 하긴, 숫자가 커질수록 소수의 개수도 로그 스케일급으로 발견되며 매우 드물어진다. 소수의 개수 역시 무한하다는 뜻이기도 하다. 숫자가 커질수록 졸라 찾기 힘들어지겠지만 말이다. -_-;;

이런 함수가 왜 근사한 이름까지 붙어 있는가 하면, n이 2 이상의 짝수일 때 ζ(n)의 값은 PI의 n승의 유리수배의 형태로 산출되기 때문이며, 더구나 이 함수는 소수의 분포와도 관계가 있기 때문이다. 이 엄청난 발견을 해 낸 사람은 불세출의 천재 수학자인 오일러이다. 특히 삼각함수의 테일러 전개와 방정식의 근의 관계를 이용하여, ζ(2) = PI^2 / 6 임을 최초로 알아내기도 했다. 따라서 그 수는 초월수라는 것 역시 덩달아 증명된 셈.

나는 증명을 뻔히 보고도 뭔 말인지 못 따라가겠던데, 사실 저것도 수학에서 가장 아름다운 방정식이라는 e^(PI*I) + 1 = 0만큼이나 그의 위대한 업적이 아닌가 생각한다. 파이, 삼각 함수, 루트, 해석학, 기하학, 복소수 등등등... 다 위로 올라가면 서로 구분이 없이 여기저기서 다 만난다는 뜻이다. 심하게 경이로운 사실이다!

Posted by 사무엘

2010/04/15 20:07 2010/04/15 20:07
, , ,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/246

C++에서 A라는 클래스를 만들었다. 이 클래스는 앞으로 당신이 만들 거의 모든 클래스들이 상속 받을 아주 기본적이고 공통적인 기능을 갖추고 있다. COM으로 치면 IUnknown, MFC로 치면 CObject 같은 기능을 하는데, 여기서는 그 예로 자체적인 reference counting 기능을 내장하고 있다고 치자.

class A {
 int nRefCnt;
public:
 A(): nRefCnt(1) {}
 ~A() {}
 int AddRef() { return ++nRefCnt; }
 int Release() { int nt=--nRefCnt; if(nt==0) delete this; return nt; }
};

이제 당신은 A로부터 상속 받은 여러 클래스들을 만든다.

class B: public A {
public:
 int nAddVal;
 B(): nAddVal(2) {}
};

class C: public A {
public:
 int nExitVal;
 C(): nExitVal(3) {}
};

그런데 C++에는 다중 상속이라는 게 존재한다.
어쩌다 보니, A의 자식 클래스들 중 서로 다른 클래스를 골라서 이들의 기능을 다 물려받은 클래스를 만들고 싶어진다. (욕심도 참 많다!)

class D: public B, public  C {
public:
 int nLast;
 D(): nLast(4) {}
};

여기서 문제가 생긴다.
이 경우, D는 B와 C의 기능을 물려받는 과정에서, B와 C가 공동으로 소유하는 A는 두 번 상속받게 된다.
32비트 기준으로 obj의 멤버 배열 순서는 대략 "1, 2, 1, 3, 4" 정도가 된다.

D obj;
obj.AddRef();

이 코드의 실행 결과는 어떻게 될까?
고민할 필요 없다. 이 코드는 컴파일 자체가 되지 않을 테니 말이다. =_=
D라는 클래스에는 A의 nRefCnt라는 멤버 자체가 둘 존재한다.
그렇기 때문에 B 쪽에 속하는 nRefCnt를 건드릴지, C 쪽에 속하는 nRefCnt를 건드릴지 판단할 수 없어서 컴파일러는 모호성 오류를 일으키는 것이다.
클래스 가계도는 보통 tree 구조가 되는데 이 경우 엄밀히 말하면 cycle이 존재하게 된다. 이 cycle을 일명 '죽음의 다이아몬드'라고 부른다.

obj.B::AddRef() 내지 obj.C::AddRef()라고 구문을 바꾸면 컴파일 에러 자체는 없앨 수 있다.
그러나 이것은 미봉책일 뿐이지 문제를 본질적으로 해결하는 방법은 아닐 것이다.
이건 클래스 B와 C가 아무 공통분모 없이, 우연히 AddRef라는 껍데기만 동일하고 의미는 완전히 다른 함수를 제각기 갖고 있는 것과 다를 게 없는 상황이다.
근본적으로는 D라는 클래스는 비록 B와 C의 기능을 동시에 상속 받았더라도 A는 단 한 번만 상속 받게 하는 방법이 있어야 한다. 그게 가능할까?

그래서 C++은 '가상 상속'이라는 걸 제공한다.
일반적으로 B라는 클래스가 A라는 클래스로부터 상속을 받았다면, B라는 클래스는 내부적으로 A의 몸체 뒤에 자기 몸체가 덧붙는다. 따라서 B 클래스의 오프셋과 A 클래스의 오프셋 사이의 간격은 컴파일 시간 때 딱 결정이 되어 버리며 언제나 고정 불변이다.

그런데 B가 A를 상속 받으면서 A를 '가상'으로 상속하면, B 클래스로부터 A 클래스의 오프셋은 자기가 별도의 내부 멤버로 갖고 있게 되며, 컴파일 시점이 아니라 실행 시점 때 동적으로 바뀔 수 있게 된다. 기반 클래스가 특수한 처리를 하는 게 아니라, 상속을 받고 싶어하는 자식 클래스가 상속을 특수한 방법으로 받아야 한다.
그래서 위의 네 클래스 A~D 중, 죽음의 다이아몬드를 해소하기 위해서는 B와 C가 A를 virtual로 상속 받게 하면 된다.

class B: virtual public A { ... };
class C: virtual public A { ... };

이 경우 B와 C는, 기반 클래스인 A가 자신과 메모리 상으로 굳이 연속적으로 이어져 있지 않더라도, B나 C 자신이 스스로 갖고 있는 부가 정보를 통해 기반 클래스인 A의 위치를 추적할 수 있다.

클래스 C만 갖고 생각하는 경우, 당연히 메모리 상으로는 A와 C가 바로 따를 것이고, C 내부에 있는 A의 포인터는 자기 바로 앞을 가리키고 있을 것이다.
하지만 클래스 D는 멤버가 ABCD와 같은 순으로 쫙 배열될 수 있으며, A와 C 사이에 B 같은 다른 클래스가 있을 수 있다. 그래도 B와 C가 A를 공유할 수 있게 된다. 공유를 하려고 이 지저분한 짓을 자처한 것이다.

자, 그럼 가상 기반 클래스의 구현 비용은 어느 정도 될까? C++에서

ptr->Function(a, b);

이라는 문장이 있고 Function이 virtual이 아닌 일반 클래스 멤버 함수라면, 위의 코드는 C 언어 문법으로 표현했을 때 대략

Function(ptr, a, b);

이 된다. 즉, this만 암묵적으로 추가되고 일반 함수와 완전히 똑같은 형태이다. 가장 간단하다.
하지만 Function이 가상 함수라면,

ptr->functbl->Function(ptr, a, b);

과 같은 꼴이 되고 오버헤드가 꽤 커진다. 우리 멤버가 가리키는 공용 가상 함수 테이블로 가서 거기서 함수 포인터를 참조하는 셈이다.
그렇다면 Function이 ptr이 가상으로 상속 받은 기반 클래스의 비가상 멤버 함수라면,

Function(ptr + ptr->baseptr, a, b);

정도. 가상 함수 정도는 아니지만 그래도 this 포인터의 위치 계산을 위해서 두세 개의 명령 오버헤드가 추가된다.
일단 다중 상속이라는 개념 자체가 컴파일러 문법상의 단순 형변환일 뿐이던 typecasting을 굉장히 복잡하게 만들었다는 점을 알 필요가 있다.

그럼 Function이 가상 상속에다가 가상 함수이기까지 하면 어떻게 될까?
그래도 functbl을 찾는데 오버헤드가 더해지지는 않는다. 어차피 각 클래스의 함수 테이블에는 자기가 지금까지 상속 받은 모든 클래스의 가상 함수들이 누적 기록되어 있기 때문에, 함수 호출을 위해 여러 테이블을 돌아다니지는 않는다.

참고로 A에 가상 함수가 있고 B와 C가 이를 제각기 오버라이드를 했는데 D가 B와 C를 동시에 상속 받고도 그 가상 함수를 또 오버라이드하지 않았다면, 컴파일 에러가 난다. B와 C 중 어느 장단에 맞춰 춤을 추리요? C++ 컴파일러는 그 정도 모호성은 자동으로 지적해 준다. C++ 컴파일러 만들기란 정말 힘들겠다는 생각이 들지 않는가?

가상 함수, 가상 상속, 멤버 함수 포인터... =_=;;
오늘날 프로그래밍 업계에서 다중 상속은 굉장히 지저분하고 흉악한 개념으로 간주되어 금기시되고 있다. C언어의 전처리기, 포인터와 더불어 현대의 프로그래밍 언어에서는 찾을 수 없는 면모가 되고 있다.
여러 클래스의 기능이 한꺼번에 필요하면, 무리하게 상속으로 해결하지 말고 해당 클래스 개체를 '멤버'로 가지는 쪽으로 가라는 것이다.

다중 상속이라든가 가상 상속이 골치아픈 게 결국은 데이터 멤버들의 오프셋 계산 때문이다. 하지만 가상 함수만 잔뜩 만드는 것은 그 클래스 자체가 아닌 함수 테이블의 덩치를 대신 키우는 것이고 클래스 자체는 가상 상속 같은 복잡한 테크닉을 필요로 하지 않기 때문에, 대다수 현대 객체 지향 언어들은 '인터페이스'라는 개념을 도입하여 이것으로 다중 상속의 기능을 어느 정도 대체하고 있다.
사실, C++의 각종 어려운 OOP 개념을 실제로 구현하는 데 비용이 얼마나 드는지를 잘 이해하고 있는 것만으로도 상당한 수준의 프로그래밍 내공을 쌓을 수 있다!

Posted by 사무엘

2010/04/14 17:19 2010/04/14 17:19
,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/245

작곡가 안 지홍 씨

앞의 글을 쓰면서 인터넷 서핑으로 자료를 찾다가.. 아주 놀라운 사실을 발견하여 추가로 글을 남긴다.

무려 라틴어 가사 코러스가 나오는 MBC 드라마 <제 5공화국>의 주제가는 안 지홍 씨가 작곡했다. 그럼 작사는? 유명한 다른 문학 작품 구절에서 따오거나 설마 라틴어로 직접 작사를?? ㅎㄷㄷㄷ
게다가 이 사람은 1995년에 방영했던 <제 4공화국>의 주제가도 작곡하고 1993년의 <제 3공화국> 주제가도 작곡했다! 현대사 정치 드라마 OST 작곡엔 아주 이골이 난 사람이구나! 모두 MBC 드라마임.

사용자 삽입 이미지
이것은 <제 5공화국> OST 도입부 멜로디를 대충 채보한 것이다. 한국어 몬데그린 가사와 함께. ^^;; Looking for You와 비슷한 상당히 빠른 템포이다.

사용자 삽입 이미지
이것이 <제 4공화국> OST의 도입부 멜로디이다. 템포는 5공화국보다 훨씬 느리지만, 도입부가 끝난 뒤에 바로 높은 라(A)음의 높은 괴성이 나오고 나중엔 클라이막스를 거친 후 ‘전땡!’ 같은 함성으로 끝난다는 점. 그리고 역시 정체를 알 수 없는 이상한 언어 가사의 장엄한 코러스라는 점은 두 곡이 매우 유사하다.
그렇기 때문에, 두 드라마는 10년에 달하는 긴 시간 간격이 있음에도 불구하고 OST는 동일 작곡자의 작품일 거라고 개인적으로 추측이 가능했다. 그리고 그 추측은 사실이었다.

사용자 삽입 이미지
이것은 <제 3공화국> OST의 도입부 멜로디이다. 가사는 없다. OST가 흘러나올 때 시꺼먼 배경으로 각종 정치인들의 진흙/금속 인형 형상이 쫙 나왔다가 사라졌는데, 이 모습이 어렸을 때 보기엔 꽤 섬뜩하고 무서웠다.
모든 악보는 본인이 그냥 기억에 의지해서 야메로 집어넣은 것임을 밝힌다.

안 지홍 씨가 누군지는 처음 듣지만, 무엇보다도 그의 기념비적인 과업은 바로..

1994년 여름, 당시 최고의 납량특집 드라마로 오늘날까지도 불멸의 명작으로 남아있는 의학 스릴러 M의 주제가 역시 이 사람이 작사· 작곡을 했다는 사실!
제목은.. <나는 널 몰라>이다.

내 영혼이 아파오네
세월은 고독을 고독은 침묵을 침묵은 미움을 기다리고 있는 걸
(이건 무슨 롬 5:3-4 같은 점층법도 아니고 뭐야..)
모르고서 시간은 흘러가네
침묵 속에 쌓여서 아무것도 하고 있지 않네 들리지 않아
어둠 속에 숨어서 아무것도 하고 있지 않네 보이지 않아
나는 널 몰라 (네가 누군지, 네가 무언지, 네가 왜 나를 찾아왔는지...!) 몰라~~!!

M은 낙태를 소재로 하여 엄청난 사회적 반향을 일으켰던 드라마이지 않던가? 아래의 성경 구절을 염두에 두고 저 노래 가사를 곱씹어 보라. 섬뜩하다. 직접 들어 본 사람만이 그 전율스러움을 안다.

영의 길이 무엇인지 또 아이 밴 여자의 태 속에서 뼈들이 어떻게 자라는지 네가 알지 못하는 것 같이 모든 것을 만드시는 하나님의 일들도 네가 알지 못하느니라. (전 11:5)

TV에서 방영될 때는 시간 관계상 1절만 나왔지만 정식 노래는 1절+간주+2절이 있었다. 간주 때는 M 특유의 변조된 악마 목소리와 으헤헤헤헤헤’ 흉악한 웃음소리까지 곁들어져, 공포 분위기를 더욱 고조시켰다. 서 태지 음반에 사탄의 메시지가 백워드 마스킹으로 녹음돼 있다고 사회적으로 이슈가 된 지 얼마 되지도 않던 시절이었을 텐데?

자, <제 n공화국>과 M 모두 짐작하셨겠지만 어김없이 단조이다.
안 지홍 씨는 뭔가 장엄한 한편으로 쓸쓸하고 암울한 느낌이 나는 OST 제작에는 정말 탁월한 재능이 있는 분 같다.
M 얘기까지 나왔으니 그런 의미에서 짤방 하나 첨가하는 걸로 글을 맺겠다.

‘착시’라고 치면 어김없이 나오는 그림이다. 언뜻 보기로는 그냥 아리따운 아가씨의 초상화인데, 눈을 뚫어지게 쳐다보면 OME (Oh my eye!) 공포물로 바뀐다고 함. 본인은 뭔지 잘 모르겠다.

사용자 삽입 이미지

Posted by 사무엘

2010/04/13 17:14 2010/04/13 17:14
, , ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/244

눈과 귀의 착시

※ 모호한 그림

사람의 두뇌는 눈과 귀로부터 오는 정보를 토대로 3차원 공간을 구성해 내는 탁월한 능력이 있다.
귀는 소리를 들을 뿐만 아니라 두 귀를 통해 이 소리가 어느 방향에서 나는지도 감지할 수 있으며,
눈 역시 두 눈으로부터 정교하게 합성된 영상을 통해 사물의 원근을 직감하고, 이를 토대로 평면 이미지로부터 3차원 공간을 인지하게 된다.

그런데 평상시에 그렇게 2차원 영상으로부터 3차원 공간을 재구성해 낼 때 쓰이는 고정 관념을 교란함으로써 온갖 착시를 만들 수 있다. 멀쩡하게 곧은 선을 휘어진 것처럼 보이게 만들 수 있고, 똑같은 물체의 크기를 서로 완전히 다르게 만들 수 있다. 원근이라는 것은 크기의 변화뿐만 아니라 색깔의 변화도 수반하는 경우가 많기 때문에, 색을 교란해서 동일한 두 색을 서로 다르게 보이게 하는 것도 얼마든지 가능하다.

이런 것보다 좀더 상위 계층으로 가서, 머리가 사물이나 글자를 인식하는 방식까지 교란이 가능하다. 이런 것들. 본인은 처음엔 '중의적인 그림'이라고 검색했는데 도무지 검색이 안 되었다. 역시 '착시'라고 찾아야 된다.

사용자 삽입 이미지

착시라기보다는 중의적인 그림의 예로 아주 잘 알려져 있다. 젊은 여성이 옆을 응시하는 모습일까, 아니면 주걱턱 노파가 전방을 주시하는 모습일까? ㅋ

※ 모호한 소리 (몬데그린)

눈에 이어 귀를 교란시켜 보자. 몬데그린이란, 인간의 정상적인 언어가 다른 언어의 환청-_-으로 둔갑하여 들리는 현상을 말한다. 간단한 예로, 군대에서는 군가도 워낙 야메로 배우다 보니 가사를 잘못 알아듣는 경우가 있다. "조국의 방패들이다"를 "조국의 깡패들이다"로 알아듣는다거나...
본인이 아는 대표적인 몬데그린으로는,

첫째, 일명 식섭송. 원조는 오스트레일리아의 어느 영어 팝송이다. 한국어 환청-_- 내용의 context를 제공하기 위해 어느 남성 나레이터가 나지막한 목소리로 나레이션을 곁들여 주는데, 이게 진짜 배 짼다. 유행한 지 벌써 10년도 더 됐지만, 그 당시 PC 통신에서 이걸 처음으로 들은 사람들은 정말 눈물 흘리면서 웃었다.
"안 불렀어(I met a man) 난 배 안 불렀어 식섭아(six feet tall) 그럼 못 써(full of muscles) ... 잊을 수 없는(he just smiled and) 개미와(gave me a) 배추만의 샌드위치"

둘째, 2차 세계 대전 당시에 독일 해군 군가로 알려진 노래.
"빨간 펜 파란 펜 뭘 바래야? 빨간 펜 야광펜 팔고 있다 ... 아는 게 힘 모르는 게 힘"
건장한 군인들이 아주 씩씩하게 필기구 판촉 활동-_-을 하는 모습을 생각하면 웃음이 작렬하지 않을 수 없다. ^^

셋째, 몇 년 전 히트 쳤던 <제 5공화국>이라는 드라마의 주제가.
"공익이 공익이 포쓰를 20번이나 혼자 다 해. 개XX XX 워 오예~ ... 전땡!"
드라마 주제가라는 특성상, 몬데그린 자막이 삽입된 동영상이 나돌면서 많은 인기를 끌었다. 가사도 뭔가 주인공을 패러디한 듯한 인상을 주는데, 그래도 당사자는 장군-_- 출신이지, 4급 공익 나부랭이는 아니다. ^^;;

정말 영락없이 한국어와 똑같이 들린다. 하지만 원래 언어는... 무려 라틴어.
원래 가사는 "비록 사람은, 사람은 (불의의) 역사를 용서(망각? 묵인? 은폐?)할지언정, 신은 그리하지 않을 것이다. 신이라면, 신이라면!" 이라는 굉장히 의미심장하고 섬뜩한 의미이다.

Posted by 사무엘

2010/04/13 09:21 2010/04/13 09:21
, ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/243

윈도우 운영체제가 인식하는 실행 파일 포맷인 PE(portable executable)의 헤더를 보면,
이 EXE/DLL이 실행되는 플랫폼(x86, x64, IA64 등등)이라든가, 이 실행 파일의 특성을 나타내는 플래그 등 여러 정보가 존재한다.
그런데 그 플래그 중에는 'Large address aware' 여부를 나타내는 플래그가 있다.
이건 무엇을 뜻하며, 왜 만들어진 것일까?

윈도우 NT는 도스의 잔재 없이 처음부터 순수 32비트로 개발된 운영체제이다.
32비트 공간에서는 최대 2^32 = 4GB 크기의 가상 메모리를 사용할 수 있는데, MS는 전통적으로 하위 2GB는 응용 프로그램이, 상위 2GB는 커널이 사용하는 구도로 운영체제를 설계했다.

그때는 램은커녕 하드디스크 용량도 4GB보다 훨씬 적던 시절. 그러니 그때 32비트는 가히 무한대에 가까운 공간이었으며, 메모리 분배를 어떻게 한다고 해도 이상할 게 없었다.
응용 프로그램은 언제나 하위 2GB만을 사용하다는 게 무슨 뜻일까?
포인터에서 32비트 크기가 다 쓰이는 게 아니라, 최상위 1비트는 절대로 1이 될 일이 없다는 말이다.

그래서 일부 잔머리 잘 굴리는 프로그래머들은 포인터에다가도 자신만의 1비트짜리 boolean 정보를 최상위 비트에다 얹고, 포인터를 쓸 일이 있으면 그 값을 잠시 제거한 후 사용했다고 한다. 흠좀무.

그런데 세상이 변해서 이제 램이 기가바이트급 스케일이 되었고, 32비트 공간만으로는 부족한 시대가 왔다. 본격적으로 64비트 시대가 도래하기 전부터 데이터베이스처럼 아주 memory-intensive한 프로그램을 돌리던 업계에서는, 유저와 커널을 2:2로 가르지 말고 3:1로 갈라서 응용 프로그램에다가 메모리를 좀더 많이 얹어 달라고 MS에다 끊임없이 요구했다. 그래서 MS는 '물리 주소 확장' 모드라는 걸 만들어 줬다.

사실, 커널도 메모리, 좀더 정확히 말하면 주소 공간이 의외로 많이 필요하다. 2:2도 오히려 부족한 감이 있다. 커널 코드를 얹고 각종 커널 오브젝트를 관리하는 메모리만 필요한 게 아니기 때문이다. 가상 메모리라는 시스템은 그 개념상 메모리를 관리하기 위한 메모리도 요구하는 법. 그와 관련되어 방대한 공간이 필요하며, 디바이스 드라이버를 얹고 돌리기 위한 메모리 등등도 따지면 결코 만만한 수준이 아니다.

3:1로 가르면 응용 프로그램이야 사용 가능한 메모리가 좀더 늘며, 종전에는 응용 프로그램이 한번에 약 1GB 남짓밖에 매핑을 못 하는 memory mapped file도 훨씬 더 큰 크기까지 확장할 수 있다. 하지만 만들 수 있는 프로세스/스레드 수가 감소하며 네트웍이라든가 운영체제의 전반적인 기능상의 한계가 매우 커지고, 운영체제가 이론적으로 관리 가능한 총 물리 메모리의 양도 줄어든다! 이 tradeoff를 반드시 잊지 말아야 한다.

그런데 문제는...
그렇게 3:1로 응용 프로그램의 메모리 주소를 확장하면...
드디어 최상위 비트가 1인 포인터 값이 응용 프로그램으로 오는 게 가능해진다는 것.
그렇다면, 예전에 놀고 있던 최상위 비트를 다른 용도로 활용하던 프로그램을 이런 확장 환경에서 돌리면.....;;; 더 이상의 자세한 설명은 생략한다.

그래서 호환성을 목숨처럼 1순위로 강조하는 MS는, 아무 프로그램이나 일방적으로 넓어진 포인터를 주는 게 아니라, 넓어진 포인터를 줘도 안전하다고 플래그가 따로 지정되어 있는 프로그램에 대해서만 제 기능을 다하도록 하는 정책을 선택했다. 그것이 바로 large address awareness이다. 이 플래그가 없이 빌드된 프로그램은 여전히 메모리를 2GB씩밖에 못 쓴다. 마치 윈도우 XP 이후에도, 별도의 매니페스트를 내장하고 있지 않은 옛날 프로그램들은 비주얼 스타일 테마가 적용되지 않는 것과 같은 맥락으로 말이다.

단, 이건 EXE에 한해서이다. DLL은 그런 선택의 권리가 없다. 확장 주소가 지원되는 EXE에 붙을 수도 있고 지원 안 되는 EXE에 붙을 수도 있으며, 어느 때건 동작을 잘 해야 한다. 따라서 DLL은 반드시 확장 주소를 지원하도록 작성되어야 한다.

본격적으로 64비트 환경이 되면서 확장 주소의 진정한 의미가 드러났다. 이제는 상위 1비트 정도가 아니라 아예 테라바이트급 메모리 주소에도 접근 가능해야 하며, 64비트 프로그램은 '확장 주소 지원' 플래그가 반드시 있어야 한다. 이 플래그가 없으면, 비록 x64 내지 IA64 아키텍처용으로 만들어진 64비트 프로그램이라 할지라도 포인터의 주소로는 여전히 무려 2GB 이내의 값만 들어온다. -_-
포인터 크기를 4바이트 int 크기로 하드코딩하고 제작된 무개념 프로그램을 최대한 쉽게 64비트로 포팅할 수 있게 배려한 것이다. 물론 이 역시 EXE에 한해서이지만 말이다.

large address aware 옵션은 비주얼 C++의 x86 플랫폼에서는 호환성 차원에서 디폴트로 꺼져 있다. 즉, 사용자가 별도로 옵션을 켜지 않으면, 2GB까지만 인식하는 프로그램을 만든다.
하지만 x64/IA64 플랫폼에서는 사용자가 별도로 이 옵션을 끄지 않으면 디폴트로 켜져 있으며, 코드가 2GB 정도가 아니라 4GB 이상의 공간도 안전하게 인식하는 것으로 간주한다. 둘이 묘한 차이가 있다는 것을 기억하자.

물론 굳이 램이 4GB가 아니더라도 64비트는 CPU가 한번에 정보를 처리하는 단위 자체가 더 크다는 점 하나만으로 32비트보다 대용량 데이터를 처리하는 성능이 더 뛰어나다. double 실수형을 하나 스택에 얹을 때만 해도 32비트에서는 CPU 명령을 최소 둘 이상 써야 하는데 64비트에서는 한 번만에 끝난다는 소리이지 않은가. 그렇기 때문에 램 용량이 32비트 크기를 초과하기 전부터도 64비트 프로세서가 개발되어 일부 제한된 영역에서 쓰이기도 했던 것이다.

잘 알다시피 64비트 윈도우는 과거 16-32비트가 그랬던 것처럼 그 정도로 지저분한 호환 계층은 제공하지 않으며, 한 프로세스 공간에 64-32비트 코드가 공존하는 것을 허용하지 않는다. 그래도 윈도우 핸들값은 여전히 32비트 범위 안에만 존재하며 32와 64비트가 값을 그대로 공유 가능하다는 게 신기하다. 하긴, 윈도우 9x에서는 윈도우 핸들값이 아예 16비트 범위에 있었지만 말이다. ^^ 썽킹이라는 말도 참 오랜만에 다시 듣는다.

Posted by 사무엘

2010/04/12 09:12 2010/04/12 09:12
, ,
Response
No Trackback , 9 Comments
RSS :
http://moogi.new21.org/tc/rss/response/242

C는 작고 쪼잔하고 오덕스럽게 만들어진 언어이다(이런 특성을 상당수 물려받은 C++도 포함). 문법에서도 이런 면모가 발견되는데, 가능한 한 예약어 개수를 줄이고 연산자와 기호만으로, 그리고 이 토큰이 쓰인 주변 문맥을 통해서 구문의 의미가 파악되도록 언어를 설계한 것이다.

비슷한 계열의 구조화 프로그래밍 언어인 파스칼과 비교하면 문법이 얼마나 극단적으로 다른지 알 수 있다. begin end 대신 간단히 { } 이다. function, procedure처럼 서브루틴을 나타내는 예약어가 따로 존재하지 않는다. 그냥 자료형과 ()가 함수를 나타내며, 아예 void라는 예약어가 따로 존재한다. var 같은 예약어도 없이 변수 선언이 바로 가능하다. forward 같은 예약어가 없어도 함수의 선두 선언이 가능하며, 별도의 array 예약어가 없이 배열을 선언할 수도 있다. 순수 가상 함수를 선언하는데  pure 같은 별도의 예약어를 추가한 게 아니라 그냥 함수 = 0이란 표현으로 대체한다. 이게 바로 C++의 사고방식이다.

이렇게 극도로 함축적인 문법 덕분에, 프로그래머는 일단 타이핑을 덜 해도 되니 좋다. 1970년대에는 언어도 기계 저수준 프로그래밍을 위해 한없이 쪼잔해져야만 했던 때임을 기억할 필요가 있다. 그 시절에 무슨 인텔리센스라든가 코드 자동 완성 같은 사치스러운 기능이 있었단 말인가?

하지만 이런 언어 구조 때문에 C, 특히 C++은 코드를 알아보고 구문 분석하기가 무척 까다로운 언어가 되고 말았다. 사람에게만 힘든 게 아니라 컴파일러 입장에서도 말이다. 단순히 암호 같은 포인터 참조와 연산자 남발 때문에 알아보기 어려운 차원이 결코 아니다.

전산학적으로 말하면 C/C++의 문법은 문맥 자유 문법이 아니다. 가령 C++ 언어의 global scope에서,

a b(c, d);
위의 문장은 C++의 경우 함수의 선언일까, 아니면 개체의 선언일까?

a<100> b;
그리고 위의 문장은 템플릿을 이용한 개체일까, 아니면 비교 연산일까?

즉, a~d의 타입이 무엇이냐에 따라 구문의 의미, 즉 파싱 방법이 완전 극단적으로 달라진다. 마치 보는 방식에 따라 GOOD으로도 보이고 EVIL로도 읽히는 중의적인 그림처럼 말이다.
C++의 문법은, 의미를 파악하기 위해 파싱을 하는데 각 토큰의 의미를 모르면 제대로 파싱을 할 수 없는 그런 구조인 것이다!

그렇기 때문에 C++ 코드는 IDE 차원에서 간단한 인텔리센스나 자동 완성 기능만 구현하기 위해서라도 코드를 전부 읽어서 사실상 컴파일을 해 봐야 한다. 게다가 전처리기를 거쳐서 #define 심볼까지 일일이 벗기면서 말이다. C#이나 자바는 C++과 매우 유사한 구문을 갖고 있고 똑같이 { } 블록 구조이지만, 문맥 자유 문법을 갖추고 있으며, 의미 분석이 C++보다 훨씬 더 간단하다.

파스칼은? 더 말이 필요 없다. 소스 코드를 단 한 번만 읽으면서 앞으로 되돌아갈 필요조차 없이 구문 분석 + 코드 생성이 다 되는 구조이다! 물론 같은 의미를 표현하더라도 C/C++보다 거추장스럽고 프로그래머가 불편한 게 더 많긴 하지만 말이다.

자바와 C#이 C++에 존재하는 모호성을 없앤 것 중 하나는 new 연산자이다.
생성자 함수 호출을 동반하는 개체는 무조건 new로 선언하게 되어 있기 때문에, new가 동반되지 않은 a b(c, d) 같은 구문은 일단 개체 선언은 절대 아니고 함수 선언이라고 보장할 수 있는 것이다.

C/C++의 문법을 더욱 문맥 의존적이고 지저분한 판타지로 바꾼 것 중 하나는 type casting이다. 별도의 type casting 연산자나 예약어가 존재하는 게 아니라 그냥 앞에다가 타입 이름을 써서 괄호로 싸는 걸로 형변환이 되게 만들어 버렸으니 원...  (a)+b 라는 구문에서 +는 a가 무엇이냐에 따라서 이항 연산자일 수도 있고 아닐 수도 있다. 포인터의 의미를 겸하고 있는 * 까지 가면 더욱 복잡해진다.

게다가 C++에서는 생성자 변환 스타일까지 허용되니 더욱 지저분해졌다! (type)value 뿐만 아니라 type(value)까지 된다는 소리. 이런 어정쩡한 문법 때문에, 소스 코드에서 명시적인 형변환이 일어나는 곳만 딱 찾기도 곤란하다는 점 역시 큰 문제였다.

보다못해 1990년대 중반에는 C++에 4종류의 별도의 형변환 연산자가 예약어로 추가됐다. static_, dynamic_, reinterpret_, const_로 시작하는 cast 연산자가 그것이다. 취지는 좋은데 C언어 철학과는 전혀 어울리지 않을 정도로 예약어 길이가 너무 긴 게 흠이다.

C++은 C언어의 호환성을 존중하여 설계되었지만, 그렇다고 해서 C의 strict superset으로 설계된 것도 아니다. 일부 문법은 바뀌거나 더 엄격해졌기 때문에, 어떤 C 코드는 C++ 언어 문법으로는 컴파일이 되지 않는다. C 영역과 C++ 영역을 엄밀하게 분리한 것도 아니고 그냥 어중간하게 C에다가 OOP 개념을 집어넣다 보니 문법은 더욱 복잡해지고, 특히 동일한 개념을 나타내는 문법이 여럿 존재하는 등( (int)a, int(a)라든가, 포인터와 참조자 중복처럼 ㅋㅋ), 참을 수 없는 지저분함에 환멸을 느끼는 프로그머도 존재할 정도이다.

그래도 오늘날까지 컴퓨터와 직통으로 네이티브 대화가 가능한 가장 강력하고 효율적인 언어라는 장점, 오로지 그거 하나 때문에 C/C++은 메이저급 언어로 군림 중이다. 더 깔끔하고 수학적으로 엄밀한 프로그래밍 언어를 좋아하는 사람이라면 이런 현실을 결코 달갑게 여기지 않겠지만 말이다.

Posted by 사무엘

2010/04/10 19:20 2010/04/10 19:20
,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/241

당신의 철도 덕력은?

Q: 연어 하면 생각나는 것은?
A: 교· 직류 겸용 전동차.
민물을 직류 전기, 바닷물을 교류 전기라고 생각하면 바로 이해가 갈 것이다.
남영-서울역 사이가 바다에서 강으로 바뀌는 일종의 절연 구간인 셈.

Q: 매일 면도할 때, 그리고 고기를 구워 먹다 철판을 갈 때 공통적으로 생각나는 것은?
A: 열차 운행 종료 후 매일 선로를 연마하고 보수하는 작업.

Q: 식당에서 여러 컵에 물을 따를 때 생각나는 상황은?
A: 각 역마다 정확하게 정지선에 맞춰 정차하는(딱 맞게 물을 따르는) 지하철 운전.

Q: 훈련소에 가 있을 때 가장 생각난 것은?
A: 서울 지하철 7호선. 7호선 노선색이 완전 국방색일 뿐만 아니라, 군대에서는 진작부터 우측통행을 하고 있어서 더욱 기억이 절실했다.

Q: 내 손전화를 보면서 문득 든 생각은?
A: 하루에 두세 번, 열차가 아주 뜸하게 드나드는 시골의 한적한 단선 철길 건널목.
전화벨이 울리는 것은 차단기가 내려가고 경보음이 울리는 것이다. 통화는 열차가 통과하는 것이다.
어쩌다 내가 먼저 전화를 거는 것은 우리 역에서 열차가 갓 출발한 것이다.
아주 드물게 발생하는 ‘통화중’은, 마주 오는 열차가 교행 대기하는 상황이다.

Posted by 사무엘

2010/04/10 07:59 2010/04/10 07:59
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/240

훈련소 갔다 온 지 3주년

그러고 보니 논산 갔다 온 지 벌써 곧 3년이 돼 가는구나. 뭐, 4주짜리 병영 캠프이긴 했지만.
군 복무 기간이 3년이었다면 그때 들어가서 이제야 제대... 정말 ㅎㄷㄷㄷㄷㄷ
그래도 한창 봄이고 날씨가 막 더워지기 직전에.. 나름 좋은 타이밍에 고생 덜 하고 잘 갔다 왔다.

내가 간 때는 마침 “상호 존중과 배려, 정감어린 인삿말”을 정책적으로 밀어붙이던 때였다.
연병장에서 “우리 처음 만남은 너무 어색했었죠 ... 바꿔 나가요 밝은 병영을 꿈꾸며” 이런 노래를 듣던 때였다. ^^;;;
물론 <멸공의 횃불>, <육군가>, <육군 훈련소가> 같은 군가도 엄청 많이 들었다.

그리고 저 때는 국기에 대한 맹세가 개정되기 거의 직전이었다. 군대에서도 의심의 여지 없이 “몸과 마음을 바쳐 충성을 다할 것을”이라고 밥 먹듯이 경례를 하고 왔는데, 그 해 가을이 돼서야 글귀가 바뀌었다는 걸 알았다. 엥? 이게 무슨? 내가 퇴소한 지 얼마 안 되어 그 해 여름에 개정됐다고 한다.

육군 훈련소에서 사용하는 제식 소총은 M16A1. 군대에 가서 실제로 총을 쏴 보면, 영화나 게임에서 듣는 총소리는 정말 조용하고 미화가 많이 된 소리라는 걸 알 수 있다. ‘탕’이 아니다. 유성음 받침으로 끝나는 소리가 아니다. 차라리 ‘딱!’, ‘빡!’에 가깝다. 콩 볶는 소리, 혹은 전기 충격으로 벌레 잡는 기구에 벌레가 들어갔다가 죽는 소리 정도 되겠다.

현실은 FPS 게임이 아니다. 과녁에 정말 안 맞는다. 조준도 힘들뿐더러, 총알이 정말 게임에서처럼 이상적인 일직선으로 날아가는 것도 아니다. 소리도 정말 고막이 떨어질 정도로 크고, 격발 직후 느껴지는 반동도 무시 못 한다.

다른 훈련소는 모르겠지만 여기는 병영과 각종 훈련 교장 사이가 멀기로 악명 높다. 이동하는 시간만 1시간이 넘는 곳도 있다. 수류탄, 각개전투가 특히 엄청 멀었던 걸로 기억한다. 가는 동안 호남 고속도로? 논산-천안 고속도로를 고가 위로 횡단하기도 한다.

군대가 아무리 편해져도 역시 군대는 군대. 입대하는 애들도 예전보다 훨씬 더 편하게 살다가 갑작스레 별세계로 들어가기 때문에, 체감하는 어려운 정도는 예나 지금이나 별 차이 없지 않나 싶다.
일단 행동을 내 마음대로 못 하고, 먹는 것까지 단체로 분대장의 통제를 받아서 해야 하고 이놈의 불침번 때문에 며칠 주기로 잠도 제대로 못 자고... 그런 게 엄청 스트레스 받고 힘들었다.

화장실엔 비데가 있기도 했다. 물론 그냥 생긴 건 아니고, 과거에 발생한 흑역사 때문에 생긴 것이다.

종교 활동은 아주 잘 보장되어 있고, 조교들도 1인 1종교 반드시 가지라고 권한다. 교회에서 유독 ‘실로암’만 나오면 애들이 다 열광의 도가니에 빠졌다. “어두운 밤에 캄캄한 밤에 새벽을 찾아 떠난다” 한 소절만 끝나면 “훈련은 전투다 각개전투!” 전투모 던지고 환호하고 난리도 아님. 실로암은 그렇게 방방 뜨는 곡도 아닌데 왜 그런 매력이 있는지 모르겠다. 종교 활동은 그냥 이 때만은 긴장도 풀고 스트레스 푸는 시간이라는 데 의미가 더 있다.

본인은 야간 행군까지 다 잘 마쳤지만, 퇴소를 앞두고 긴장이 풀리면서 완전히 탈났다. 등산을 가서 산꼭대기까지 성공적으로 오른 후, 하산하다가 조난당한 것과 정확히 같은 상황이다. 어느 때보다도 즐거워야 할 마지막 퇴소식? 수료식 날에 목소리가 다 쉬고 몸살감기가 도져서 끙끙 앓아누웠고, 퇴소식에도 참석 못 했다.
수료식을 마친 훈련병들은 곧장 사복으로 갈아입었고, 혼자 나가는 인원과 부모님이 오신 인원이 분리되어 마지막 순간까지 분대장의 통제를 받다가 해산· 귀가했다. 야호!

잠시나마 병영 생활을 해 본 것을 계기로, 우리나라의 건국 과정, 6 25, 그리고 특히 이 승만 초대 대통령에 대한 관심이 그때부터 늘었다. 그래서 그 해 현충일엔 일부러 서울 현충원에 가 보기도 했다. 그의 저서 <Japan Inside Out>이 <일본 그 가면의 실체>라는 제목으로 국내에 출간되어 나온 것도 아주 공교롭게도 2007년 그 때였으며 본인은 이 책을 구입해서 읽었다. 2005년이 본인이 박 정희에 대해 공부한 해였다면(2005년도 재미있는 사건이 엄청 많이 터진 해였다), 2007년은 이 승만을 공부한 해였던 것이다.

Posted by 사무엘

2010/04/09 12:54 2010/04/09 12:54
,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/239

« Previous : 1 : ... 197 : 198 : 199 : 200 : 201 : 202 : 203 : 204 : 205 : ... 221 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Site Stats

Total hits:
3043077
Today:
269
Yesterday:
2435