« Previous : 1 : ... 43 : 44 : 45 : 46 : 47 : 48 : 49 : 50 : 51 : ... 221 : Next »

1. 본질적이지 않은 오해와 중상모략

세상에는 기독교의 탈을 쓴 이단 사이비가 여럿 있다. 이단들은 단번 속죄 구원의 영원한 보장 교리를 이상하게 배배 꼬는 경향이 있다.
아예 구원의 상실, 행위 구원을 가르치는 건 예사이고, 반대편 극단으로 가서 이제 죄 용서 받았고 구원받았고 무슨 짓을 해도 지옥은 안 가니 "니 꼴리는 대로 살아도 된다, 심지어 일체의 참회나 회개를 할 필요도 없다" 이렇게 롬 6:1-2를 정면으로 거스르는 헛소리를 하는 곳도 있다.

이런 소리를 정상적인 크리스천이 들으면 "그건 성경의 가르침을 일부만 그것도 아주 잘못 적용한 이단 교리일 뿐이다. 성경은 그런 막장 결론을 의도하거나 조장하지 않으며, 우린 그런 가르침하고는 아무 관계 없다"라고 항변하고 싶을 것이다. 영화 밀양에서 묘사된 것처럼 "나는 신에게 다 용서받았으니까 괜찮아~" 이러는 양심 마비자를 제정신 박힌 크리스천이라고 간주하는 사람은 아무도 없다.

그런데 비슷한 논리로, 진화론에 대해서도 진화론적 세계관, 무신론, 유물론, 우생학, 사회 진화론 이런 것까지 연루시키면서 이놈의 사탄 마귀적인 진화론의 영향을 받아서 나치즘과 공산주의가 생겨났고 젊은이들의 정신이 황폐해지고 어찌 됐네 이렇게 프레임을 씌운다면... 단순히 과학 이론으로서 진화론을 지지하는 사람하고는 더 대화를 할 수 없을 것이다. 지금은 진화론자라도 "흑인은 인간과 짐승 사이에 진화가 덜 된 생물이다" 이딴 식으로 생각하지는 않기 때문이다.

이렇게 말하는 나도 개인적인 소신은 당연히 "이 우주와 생명이 우연히 저절로 생긴 게 아니고 절대자가 있다"라는 신의 창조이다. 그 정도 진화가 가능하다고 해서 인간 정도의 고등한 생명체가 그런 진화의 산물로 저절로 생기는 건 가능하지 않다고 본다.
하지만 믿음을 발휘할 영역과 과학 관찰로 승부할 영역, 직접적인 관계가 없는 파생 효과 내지 오해· 중상모략 같은 것은 분명하게 분간해서 주장해야 할 것이다.

2. 과학 관찰은 종교색과 무관

이 세상 학계에서는 누구 말마따나 그저 하나님을 인정하기 싫어서 과학 시간에 창조론을 가르치지 않는 걸까? 20세기에 천문학계에서 벌어졌던 논쟁을 생각해 보면, 이 문제를 좀 다른 관점에서 관찰할 수 있을 것이다.

천동설과 지동설, 창조와 진화 같은 것과 마찬가지로.. 천문학계에서는 우주의 기원에 대해서 대폭발설(일명 빅뱅)과 정상 우주론이 첨예하게 대립했다. 그 당시엔 두 이론이 모두 상대편 이론을 완전히 제압할 정도로 과학적 증거가 충분하지 못했기 때문이다.

종교적인 심상을 고려하면 오히려 빅뱅이 뭔가 시작과 기원, "빛이 있으라" 같은 창세기 1장 느낌이 물씬 풍긴다. 게다가 빅뱅이라는 개념을 1930년대 초에 최초로 제안했던 사람은 천문학자 겸 현직 가톨릭 신부이기까지 했다! 그래서 무신론 과학자들은 이를 심리적으로 거부했다.

이와 달리 정상 우주론--딱히 기원이 없고 영원 전부터 영원까지 동일하게 있음--은 벧후 3:4의 심상과 비슷하다. 그리고 성경에서는 이건 잘못된 사고방식이라고 깐다. -_-;;
그랬는데.. 훗날 우주 배경 복사라는 게 발견되면서 이 주제는 빅뱅이 맞는 것으로 사실상 결론 지어졌다. 정상 우주론은 천동설 급으로 완전히 폐기된 건 아니지만 거의 소수설 비주류로 전락했다.

요지는.. 세상 학계도 과학적인 증거만 있다면 창세기 냄새가 좀 풍기는 학설이라도 받아들인다는 것이다. 공립 학교에서 과학 시간에 창조론(?)을 가르치지 않는 것은.. 세상 인명 사전에서 예수에 대해 "십자가에 못 박혀 죽었다" 다음으로 "사흘 만에 부활했고 승천했다"라고 차마 쓰지 않는/못하는 것과는 성격이 약간 다르다.

비슷한 예로 초능력이니 UFO니 하는 것도 꼭 기독교계에서 사탄의 미혹 운운하며 난리를 치지 않더라도, 과학적으로 검증 가능하지 않으면 이 바닥 종사자들이 알아서 배척한다.

물론 과학이 만능은 아니고 과학으로 알 수 없는 현상도 많다. 하지만 그 바닥에 있는 사람들의 집단 지성은 최소한의 합리성을 지니고 있다.
그런데 정작 창조 과학 진영에서는 빅뱅을 여전히 배척한다는 게 아이러니이다. 빅뱅이 기원이라는 개념 자체는 성경과 일치하지만 연대기는 젊은 우주를 지지하지 않기 때문이다.;;

내 개인적으로는 창 1:1,3이나 벧후 3:4가 지구를 넘어 우주의 기원을 직접적으로 말하는 구절인지 잘 모르겠다. 이사야서에 나오는 "땅의 원 위에 앉으신 이"가 딱히 지구가 둥글다는 걸 말하지는 않으며, 계시록에 나오는 "땅의 네 모퉁이"가 지구가 평평하다는 걸 말하지는 않는다고 본다.

성경에 따르면 세상이 과거에 있었던 세상, 현 세상, 다가올 세상이라는 세 종류가 존재하고 하늘도 세 계층이 있다는 것 정도까지만 알 수 있다. 그 개념이 현대의 지질학이나 천문학이 밝혀낸 자연의 모습과 어떻게 대응하는지는 인간이 적절히 잘 풀어야 하는 숙제일 것이다. 다만, 성경이 문자적으로 사실이기 위해서 반드시 젊은 우주, 젊은 지구를 고집할 필요는 없다는 것이 본인의 소신이다.

3. 창조 과학의 정체성

창조 과학회라는 곳에서 주장하는 바는 다음과 같이 분류할 수 있다.

  • 성경 내용은 문자적으로 옳고 정확하며, 과학적으로 사실이다.
  • 이 세상(우주, 지구, 생물..)은 우연히 저절로 만들어질 수 없으며 신에 의해 창조되었다.
  • 지구와 우주의 나이는 젊다.

성경이 오류가 없고 문자적으로 해석해야 할 대상이라는 것은 본인도 적극 동의하는 바이다. 창세기의 6일, 계시록의 1000년이 대표적인 예이다. 성경에 나오는 각종 인물, 명칭과 숫자들, 사건들은 대놓고 비유 허구라고 명시된 게 아닌 한 당연히 역사적으로 과학적으로 정확한 레알이다. 피나 일부 위생 관념에 대해서 말한 것은 분명히 시대를 앞섰던 것도 있다.

그런데 한편으로는 성경이 원자와 분자를 논하고 definition, theory, lemma가 나오는 이공계 학술서적 스타일로 저술된 책은 또 아니다.
성경에는 하늘에 해와 달과 별들만 나오지, 당장 금성 화성 목성이 나오는 것도 아니다. 그런 맥락에서 난 성경에 딱히 지구 자체가 둥글거나 평평하다고 말하는 암시는 없다고 생각한다. 욥기 38장에서 하나님의 질문은 이런 식으로 기록되지 않았다~!

“내가 우주를 한 점에서 시작해서 대폭발 시킬 때 네가 어디 있었느냐? 니가 인간 DNA의 염기 서열을 아느냐? 양성자와 중성자가 서로 붙어 있고 전자가 원자핵을 돌게 하는 힘이 어디서 나고 그게 무엇 덕분에 가능한지 니가 아느냐?
길바닥의 이끼도 해내는 광합성의 명반응 암반응 메커니즘을 니가 아느냐? 네가 전자기파의 속도가 유한하다는 것을 알고 그것을 능히 측정할 수 있겠느냐?”


그러니 성경이 문자적으로 사실이긴 한데.. 도대체 어느 문맥과 scope까지 문자적인 사실인지, '모든'이라고 했을 때 얘는 도대체 어느 범위의 전체를 말하는 건지 정도는 그래도 최소한 성경이 자체적으로 정해 놓은 원칙에 따라 분간을 해야 한다. 그러니 창조 과학이라 해도 과학뿐만 아니라 바른 신학을 저변에 깔고 있어야 한다.

그 다음 지적 설계는 심증으로서는 매우 유력하며 신앙을 갖기에 충분한 근거가 될 수 있다. 시 19나 롬 1:19가 말하는 일명 자연 계시 말이다. 하지만 신의 존재는 과학으로 증명도 반증도 제대로 할 수 없으며, 이것이 과학의 관점에서 '물증'이 될 수는 없다.
이건 당연한 귀결 아닌가? 그렇다 하더라도 예수 믿는 사람들은 조금도 슬퍼하거나 노여워할 필요가 없다.

그래서 창조 과학 진영에서 위의 두 명제.. 즉, 성경의 사실성과 지적 설계를 입증하기 위해서 그 다음으로 끄집어낸 카드가 바로 젊은 지구이다.
지구와 우주의 나이가 젊다는 학설? 가설 자체는 신학하고 전혀 무관하게 오로지 과학만으로 승부할 수 있는 분야이다. '세상이 우연히 만들어질 수 없다', '성경은 사실이다' 이런 것과는 좀 성격이 다르다.

이게 제대로 진행됐다면.. 세상 학계에서도 "난 무신론자여서 성경이니 신이니 그딴 건 모르고 믿지도 않음. 하지만 그와 별개로 지층을 관찰하고 물리 법칙을 생각해 보니 우주와 지구의 나이는 1만 년 이내로 보인다" 이렇게 주장하는 과학자가 나와야 한다.
하지만 현실은 과연 그러한가? 창조 과학이 성경과 과학 중 하나라도 제대로 잡고 있는가..?? 이에 대해서는 개인적으로 무척 우려하지 않을 수 없다.

나로서는 젊은 우주/지구에 대한 일말의 증거가 있다면 그건 아담 이래로 재창조된 현 세상의 연대기가 젊다는 과학적 증거가 될 수 있다고 본다. 그러니 good luck~! 우주 배경 복사나 방사선 연대 측정법의 허를 찌르면서 부디 과학계에 좋은 기여를 하길 바란다. 무슨 지구 온난화 허구설, 지구 평평 같은 이상한 유사과학 음모론으로 치부되지 말고 말이다.

Posted by 사무엘

2021/06/04 19:35 2021/06/04 19:35
, , , , , ,
Response
No Trackback , 7 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1895

2021년이 된 와중에 문득 생각을 해 보니.. Windows 8과 8.1은 정말 존재감 없이 소리소문 없이 싹 묻히고 사라진 것 같다.
XP, 7 다음에 바로 10이다. 8 계열은 20년 전의 ME만치 망한 건 아니지만 Vista보다는 더 흑역사이다.

사실 난 개인적으로는 옛날에 XP 다음의 Vista는 그 정도로 욕 먹을 퀄리티는 아니었으며, 일부는 오해와 누명을 쓴 것도 있다고 생각한다. 5년 만에 출시됐다 보니 갑자기 시스템 요구 사항이 너무 높아지고 일부 하드웨어와 호환이 깨지고, 사용자 계정 컨트롤이 도입된 게 반발을 일으켰을 뿐.. 그건 시간이 해결해 줄 수 있고 사후 재평가의 여지가 있는 이질감이었다. 7이라도 XP 다음에 바로 갑툭튀였다면 맞았을 질타를 미리 맞아 준 것의 비중이 크다.

그럼 8 계열은 사정이 어땠을까? 잠시 10여 년 전 당시 상황으로 되돌아가 보자.
이때는 나름 격변기였다. 아이폰이니 안드로이드니 하면서 본격적으로 스마트폰이라는 새로운 컴퓨팅 생태계가 조성되고 있었으며, 마소에서도 초대 원로 경영진(빌 게이츠, 스티브 발머)이 대거 은퇴하고 세대가 교체되고 있었다. 사내 분위기가 크게 요동칠 수밖에 없었을 것이다.

이 와중에 얼리어답터들은 “Windows가 7 이후로 2010년대엔 도대체 어디까지 변모할까? 마소는 이 시점에서 어떤 결정을 내릴 것이며 PC와 모바일과의 접목은 어떻게 이룰까?”라고 기대와 주목을 잔뜩 하고 있었다. 그때는 다음 버전이 심지어 재래식 NT 커널을 버리고 처음부터 다시 개발된다는 루머까지 나돌았다. (실제로는 그럴 리가.. NT 커널은 지금 Windows 10에서도 건재함! 없어질 수가 없다)

그랬는데.. Windows 7의 차기 버전인 8은 결과적으로 뭔가 구심점 없고 나사 빠진 듯한 망작이 되었다.
비주얼이 다시 심플해진 것은 그렇다 친다만, 갑자기 시작 메뉴가 없어지고 전체 화면으로 바뀐 것은.. PC와 스마트폰의 크기와 용도의 차이에 대한 고찰이 결여된 자충수였다. 게다가 8은 시작 메뉴 버튼 자체가 없었다~! 이런 제품이 어째 QA나 사용성 테스트를 통과하고 출시됐는지 모르겠다.

더 옛날인 2000년대엔 새 밀레니엄 컴퓨팅을 표방하면서 인텔 Itanium이라는 64비트 프로세서가 출시되었고 Windows는 2000뿐만 아니라 ME도 나왔었는데.. 아시다시피 Itanium과 ME는 대차게 망했다. 그런 것처럼 2010년대를 개막했던 Windows 8은 사용성 면에서 큰 혹평을 받으면서 XP와 7의 아성을 넘지 못했다.

그리고 사실은 스마트폰 OS의 쟁탈전도 매우 싱겁게 끝났다. 지금 다들 경험하시는 바와 같이 안드로이드 아니면 iOS로 양분되었고, 마소는 이 바닥에서의 주도권을 완전히 빼앗겼다. 심지어 웹 브라우저마저 IE 독점은 진작에 물 건너갔고 Edge 브라우저도 자체 개발을 포기하고 크로뮴 엔진에 흡수되지 않았는가?
국내로 치면 모바일에서 주도권을 완전히 주도권을 빼앗기고 삼성 전자와는 정반대의 처지가 된 LG 전자와 비슷하다고 하겠다..;

그러니 8 시절부터 Windows에 도입된 Metro 앱이니 하는 것 역시 폰에서는 볼 일이 없어졌다. Universal이라는 수식어가 무색해졌고 지금은 그냥 스마트폰 같은 큼직한 글자의 UI 엔진이 제공되는 특이한 프로그래밍 플랫폼? 가상 머신?처럼 됐을 뿐이다. NT 커널 없이 새로 개발된다는 엔진이 이런 곳에 적용된 거라고 보면 되겠다.

그렇게 결판이 난 뒤 마소에서는 스마트폰용 OS가 아니라 그냥 기존의 데스크톱용 Windows 10을 스마트폰용 CPU인 ARM64에다가 포팅하는 식으로.. 즉, 자기 정체성을 유지하면서 모바일 환경에다 손을 내민 상태이다. 요즘 PC와 스마트폰의 경계가 많이 모호해지긴 했지만 그래도 PC는 안 쓸 때도 24시간 내내 켜 놓는 물건은 아니며, 떨어뜨려도 될 정도로 튼튼한 물건도 아니라고 여겨진다. 그리고 스마트폰은 프린터나 재래식 하드디스크 같은 장치와는 여전히 친숙하지 않다.

그렇게 Windows 8 내지 8.1은 2010년대 초반 마소의 시행착오가 깃들어 있는 비운의 작품이 됐다.
개인적으로는 Windows 제어판이 Metro 기반인 ‘설정’으로 야금야금 대체된 건 글쎄.. 그냥 reinvent the wheel 삽질 같고 멀쩡한 인도 보도블록을 교체하는 듯한 느낌이다. 기존 제어판에 익숙한 사용자를 괜히 헷갈리게만 하고 말이다.
지금도 키보드의 반복 속도를 최대로 조절하는 것만 해도 설정에서 가능하지 않기 때문에 재래식 제어판으로 가야 한다.

그리고 프로그램의 제목 표시줄에 제목이 가운데 정렬로 표시되었던 Windows는 과거의 16비트 시절 1~3.x 아니면 후대의 8/8.1밖에 없다~!! 거기 말고는 MS Office가 뜬금없이 2007부터 현재까지 가운데 정렬을 하며 따로 노는 중이다.

나머지 Windows 95, NT4부터 7, 그리고 지금의 Windows 10은 다 왼쪽 정렬이다.
Windows의 역사상 32/64비트 시대에 프로그램 제목을 가운데에다 표시했던 버전, 그리고 시작 버튼이 없던 버전이 있었다는 걸 기억하는 사람이 얼마나 있을까? 문득 궁금해진다.

한글 IME의 개발이라는 관점에서 보면 Windows 8 계열은 메트로 앱에 대해서는 키보드 포커스를 얻었을 때 가/A 한영 상태를 IME가 근처에다 팝업 창으로 수동으로 잠깐 띄워주고, 상태가 바뀌었을 때도 그걸 띄우는 수고를 해 줘야 하는.. 약간 원시적인 조치가 필요하던 유일한 운영체제였다.
메트로 앱은 전체 화면에서 실행되는 관계로, 운영체제의 기존 도구모음줄(language bar)의 보조를 전혀 받을 수 없기 때문이다.

이것도 아무리 생각해 봐도 뻘짓이었다. 도구모음줄을 IME가 제각각으로 구현해야 했던 1990년대도 아니고.. Windows 10부터는 메트로 앱도 창 모드로 실행 가능하고, 입력기의 상태를 작업 표시줄(task bar)에서 확인 가능하기 때문에 저렇게 할 필요가 없어졌다. 즉, 저 관행 역시 일회적인 이벤트로 끝났다는 것이다.

이상. 이 글에서는 Windows 8 계열에 대해 주로 다뤘지만, 걔네 말고 Windows라는 운영체제 제품에 대해서 개인적으로 의아하거나 궁금한 점을 더 꼽자면 다음과 같다.

1. 비현실적인 권장 사양

마소에서는 Windows 7 64비트 정도의 시점을 마지막으로.. 자기 운영체제의 동작을 위한 최소 PC 사양과 권장 사양을 더 올려서 기재하지 않고 있다.
7이 램 최소 1GB 이상, 권장 2GB 이상인데.. 이게 Windows 8과 10까지 동일하다. 하지만 이건 개인적으로 생각하기에 완벽한 허위· 과장 광고라고 여겨진다.

도대체 어느 정도 돌아가는 게 최소 사양이고 어느 정도로 여유가 남는 게 권장인지 정확한 정의는 잘 모르겠다만.. 요즘 Windows 10은 램 8GB에서 돌려도 부팅 직후에 크롬 브라우저 창 몇 개나 MS Office 프로그램, Visual Studio 같은 걸 열면 메모리가 거덜난다. 정말 못 해도 16GB는 돼야 넉넉하다는 느낌이 든다.

Windows 7에서야 최소 1GB, 권장 2GB는 수긍할 만하며 램 8GB는 펄펄 날아다니는 용량이다. 하지만 10은 절대 그렇지 않다. 아무리 못 해도 최소 2, 권장 4 이상으로는 수정돼야 하리라 여겨진다. 그리고 요즘도 32비트 에디션이 나오고 있나 모르겠는데.. 걔는 이제 단종시켜도 될 것이다.

2. 서버 제품군의 존재감

Windows의 개인 사용자용 제품군은 아시다시피 2015년부터 10이라는 단일 브랜드 하에서 주기적인 업데이트를 통해 프로그램을 진화(?)시키는 형태로 바뀌었다. 하지만 서버 제품군은 여전히 2008, 2012, 2016 등의 연도 브랜드를 쓰고 있어서 다소 이질적이다. 이런 이원화된 버전 넘버링이 언제까지 계속될지.. 마치 Office 365와 기존 Office 20xx 패키지의 관계만큼이나 궁금해진다.

그리고 더 결정적으로는 기업 같은 데서 서버 제품군을 쓰는 곳이 있긴 한지..?? 이건 마치 Itanium 컴퓨터만큼이나 본인이 태어나서 지금까지 한 번도 구경해 보지 못했다.
왜냐하면 서버 제품군을 쓸 정도의 컴퓨터라면 차라리 유닉스 터미널이 내장돼 있는 리눅스나 맥OS를 쓰고 말지 Windows를 쓰지는 않기 때문이다.

서버 에디션은 원래 Windows NT나 2000까지는 동일 버전의 바리에이션 형태로만 존재해 왔다. 그랬는데 XP 때는 웬일인지 Server 2003이라고 제품명은 물론 내부 버전 번호까지 다르게 붙일 정도로(5.1 vs 5.2) 차별화를 했었다. 그 대신 XP는 개인용 에디션이 홈 vs 프로로 더 세분화됐다.
그 뒤로 서버 제품군은 버전 번호는 클라이언트와 동일하지만 제품명은 저렇게 Server 20xx 식으로 나가고 있다.

3. 자잘한 UI 버그

  • 가끔씩 재래식 TSF 입력 도구모음줄과, 작업 표시줄 쪽의 Windows 10 스타일 입력 상태 아이콘이 동시에 나타나는 버그는 꽤 유명했는데 19xx나 20xx 사이에서 드디어 고쳐진 것 같다. 요즘은 눈에 띄지 않는다.
    하지만 caret (cursor)이 여섯 번 정도 깜빡이다가 깜빡임이 중단되는 버그는 여전히 건재한 듯하다. Windows 3.1 이래로 이런 특이한 현상은 처음이다.

  • 가~~~끔. 컴을 절전 모드에서 꺼냈을 때나 프로그램 창을 전환했을 때.. 이미 띄워져 있는 프로그램 창들이 부르르 다시 그려지면서 깜빡이고 떨리는 현상.
    내 개인용 컴과 회사 컴이 모두 그러는데 좀 보기 거슬린다.
    윈10 초창기에는 이런 현상이 없었고, 특정 컴에서만 그러는 것 같지는 않은데 왜 그러나 모르겠다. (2004대 버전 기준)

  • 컴퓨터에 따라서 케바케이긴 하지만.. 메뉴가 '파일, 편집' 같은 라벨의 우측 하단 ┗ 모양이 아니라 ┛ 왼쪽으로 펼쳐지는 기괴한 현상이 왜 발생하는지 모르겠다. 아랍권도 아닌 멀쩡한 한국어/영어에서 말이다.
    로컬라이즈나 사용 접근성을 위해 필요한 옵션이라면 제어판에라도 옵션을 정식으로 갖다 놓든지..? 저런 동작이 왜 존재하는지도 모르겠고, 또 사용자의 동의 없이 불쑥 바꿔 놓고는 원상복구를 왜 레지스트리 수정을 통해서 해야 하는지 모르겠다.

Posted by 사무엘

2021/06/02 08:36 2021/06/02 08:36
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1894

1. 자가 음향의 재송신/녹음 문제

전화기에는 수화기 쪽의 소리를 키워서 굳이 귀를 기기에다 갖다대지 않아도 소리가 충분히 크게 들리게 하는 '스피커폰' 모드라는 게 있다. 이건 여러 사람이 통화 내용을 동시에 들어야 하는 모임이나 원격 회의 같은 데서 유용한 기능이며, 중공 폐렴으로 인해 비대면 모임이 활성화되면서 이런 기능도 더욱 즐겨 쓰이고 있다.

그런데 한 가지 의문이 드는 건.. 그럼 전화기는 자기 스피커폰에서 난 소리를 또 송화기를 통해 상대편으로 보내고, 상대편에서도 자기가 받았던 소리를 크게 틀어 놓느라 또 우리에게 보내다 보면.. 마치 거울을 앞뒤로 평행하게 배치한 것처럼 동일한 소리가 무한히 송수신을 반복하며 울리게 되지 않겠냐는 것이다. 전화기는 무전기가 아니니, 송신과 수신이 둘 다 동시에 행해지기 때문이다.

이거 무슨 전화기의 역설처럼 들리는데.. 직접 해 보면 그런 일은 발생하지 않는다.
비슷한 예로, 한 컴퓨터에서 A라는 프로그램에서 사운드를 크게 틀어 놨는데 B라는 프로그램에서 마이크를 이용해 그걸 자가 녹음하는 건.. 다들 해 보시면 알겠지만 이 역시 잘 되지 않는다. 사람 귀에는 똑같이 크게 들리는데 바깥 소리만 녹음되고 자기가 내는 소리는 녹음되지 않는다. 뭔가 순환 논리를 일부러 막는 로직이 있는 것 같다.

2. 자석

대형 마트의 에스컬레이터는 지하철역이나 백화점에 있는 여느 에스컬레이터와는 형태가 많이 다르다.
쇼핑 카트를 동반한 채로 층을 오르내릴 수 있게 하기 위해 경사가 굉장히 완만하며, 계단이 아니라 경사만 진 무빙워크 형태이다. 게다가 이용 중에 카트가 미끄러져 내려가지는 않게 바퀴를 자석 같은 걸로 착 고정도 해 준다. 어떤 원리로 그 무거운 카트를 고정해 주는지 '사물궁이 잡학지식' 같은 데서 다룰 법도 해 보이는데 아직 딱히 못 본 것 같다.

3. 키보드에 들어가는 건전지

직장에서 사용하는 무선 키보드가 건전지가 다 소모돼서 AAA 사이즈 건전지 2개를 안에다 집어넣었는데..
키보드 배틀을 앞두고 총에다가 총알을 장전하는 것 같은 느낌이었다.
그도 그럴 것이 AAA 건전지의 길이가 44mm인데,
NATO 표준 소총 총알 길이가 구경 5.56에 길이 45mm..
게다가 건전지 색깔도 황동 탄피를 연상케 하는 금색.. ㅋㅋㅋㅋ

자동차건 비행기건 총알이건.. 고속으로 움직이는 물체는 무작정 동그란 구형으로만 만드는 게 장땡이 아니다. 단면적 대비 유체역학적으로 공기 저항을 덜 받는 디자인은 따로 있다.
그렇기 때문에 속도 상관없이 극한의 수압을 견뎌야 하는 심해 잠수정이나 동그랗게 만들곤 한다.

반대로 우주 탐사선은 전혀 유체역학적으로 만들 필요가 없기 때문에 그냥 건물 구조물에 더 가까운 모양인 거고..
BB탄 같은 동그란 납덩이 총알, 또는 볼링공 같은 동그란 대포 탄환은 중세나 길어야 근대까지만 현역으로 쓰이다가 완전히 자취를 감췄다.

지금으로부터 몇백 년 전엔 화약이란 게 얼마나 비싸고 귀한 물건이었는데.. 게다가 그 화약도 총 한 발 쏘고 나면 앞이 안 보일 정도로, 전투를 제대로 치를 수 없을 정도로 짙고 뿌연 연기를 내는 놈밖에 없었는데..

그에 비하면 지금은 총알이 얼마나 싸고 흔해 빠진 존재가 됐으며 1초에도 총알을 드르르륵 갈기는 기관총 기관포까지 일상이 된 지 오래다. 이 역시 눈부신 과학 기술의 발전 덕분이라고밖에 생각할 수 없다.
음 뭔 얘기를 하다가 갑자기 .. 오늘도 키보드 배틀 파이팅이다~ ^^

4. 소음

손톱깎이는 가위나 병따개 같은 지레 기반의 다른 물건하고는 어떤 차이가 있어서 손톱을 자르는 순간에 생각보다 큰 짤깍 소리가 나고, 손톱이 꽤 멀리까지 튀는 걸까? 개선하는 방법이 없을까..? 아주 간단한 것 같으면서도 그 이유를 물리학적으로 설명하기 쉽지 않아 보인다.

그리고 손톱깎이하고 완전히 다른 영역이겠지만 진공 청소기도 여느 평범한 선풍기나 헤어 드라이어와 달리 왜 이렇게 시끄러울까? 내연기관을 사용하는 것도 아니고.. 바람을 내뿜는 것하고 빨아들이는 건 방향만 다른 게 아닌지..?? =_=;; 잘은 모르지만 소음은 기술적으로 더 줄이기는 힘들다고 한다.

5. 구기 종목

세상에 존재하는 공놀이들은 경기 형태 내지 득점 조건이 크게

  • A형: 자기 자리에서 상대방과 공을 주고받다가 확 세게 던져서 상대방이 못 받게 만들기
  • B형: 아니면 여러 명이 우루루 상대방 진영까지 직접 쳐들어가서 공을 상대편 골대에다 집어넣기

이렇게 둘 중 하나로 나뉘는 것 같다.

종목 득점조건 공 크기 수단 이동반경 인원 비고
배드민턴 A형 제일 작고 가벼움 라켓 내 자리만, 좁음 1~2인  
탁구 A형 작음 라켓 아주 좁음 1~2인 탁자
테니스 A형 중간 라켓 내 자리만, 좁음 1~2인 장비만 바뀐 배드민턴 같음
하키 B형 작음 라켓 전체, 넓음 11인  
야구 ?????? 중간 배트, 글러브 전체, 넓음 9인 룰이 제일 기괴하고 세팅할 것도 많음
배구 A형 맨손 내 자리만, 보통 6인  
농구 B형 맨손 전체, 넓음 5인  
축구 B형 전체, 아주 넓음 11인 골키퍼

A는 작은 공을 도구를 써서 조종하는 편이고 B는 비교적 큰 공을 다룬다.
하지만 하키는 공은 A과 비슷하게 다루면서 득점은 B와 비슷하게 하는 일종의 짬뽕에 속한다.
그 반면, 배구는 반대로 공의 형태는 B에 가깝고 득점 조건은 A에 가깝다.
이런 구기종목들은 여자 선수단도 존재하긴 하는데, 남자는 아무래도 축구가, 여자는 배구 쪽이 유명한 것 같다. 작은 공을 다루는 종목은 큰 공 종목에 '비해서'는 피지컬을 덜 타는 듯..

끝으로.. 난 2021년 현재까지도 야구는 룰과 득점 조건을 전혀 모른다. 빠따로 공 치고 나서 선수들이 무슨 역할로 나뉘어서 무엇을 위해서 열심히 달려가는지 여전히 모름. 그러니 관중들이 무엇에 열광하는지도 알 리가 있나.. 평생 죽을 때까지 모르고 지나갈 수도 있다. ㄲㄲㄲ

6. 무덤

이민 간 교포는 2세대 3세대 n세대로 갈수록 부모의 모국어를 잊어버리고 현지인과 결혼하고 현지 문화와 동화되면서 어지간해서는 결국 현지인이 된다. 코리아타운, 차이나타운 같은 곳은 새로 이민 오는 사람이 계속 있기 때문에 유지되는 것이지 싶다.
친척은 혈연의 근거인 부모/조부모님이 돌아가시고 서로 촌수가 증가하면 볼 일이 없어지며, 연락과 교류가 차츰 끊기고 서로 남남이 된다.

그것처럼 조상 산소도 몇십 년이 지나고 직계 후손이 죽고 나면 관리하는 사람이 없게 되고, 베고 또 베어도 계속 솟아나는 잡초들에 뒤덮혀서 결국 자연과 하나-_-가 된다. 유해뿐만 아니라 관과 무덤 봉분까지 그렇게 된다는 것이다.
잡초가 생명력이 끈질겨서 별로 티가 안 나는 거지, 인간의 무덤도 골프장만큼이나 나름 산림을 많이 파괴함으로써 유지되는 것 같다.

죽은 사람이 언제까지나 땅을 그렇게 점유하면서 후손들의 수고까지 요구할 수는 없다. 그러니 유해도 무슨 태풍 이름이나 야구 선수 번호처럼 영구 결번시킬 만치 충분히 유명한 사람, 좋은 업적을 남긴 사람, 지위가 높은 사람에 대해서만 묘지를 만들고, 나머지는 화장+봉안당 안치로 일괄 변경하는 게 합리적이어 보인다. 아무리 자기 부모님이라 해도 돌아가셨다고 삼년상...;; 어휴~ 옛날 유교 문화--변질됐건 아니건--는 너무 갑갑하고 비생산적이었다.

시대가 흐르면서 설· 추석 같은 명절의 풍속이 확 바뀌었듯, 매장 대신 화장, 미리 유서 써 놓기처럼 사망과 장례 관련 문화도 바뀔 필요가 있으며 실제로 바뀌고 있기도 하다.

Posted by 사무엘

2021/05/30 08:35 2021/05/30 08:35
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1893

여러 어휘 관련 이야기들

1. 접두사

한국어에서 '반'이라는 접두사는 반대· anti라는 뜻이 있고(반작용, 반중력, 반물질, 반동..), half라 하더라도 반자동, 반원, 반계탕(...)처럼 뭔가 온전· 완전하지 않은 반쪽짜리라는 뜻을 지닌다.

하지만 '반영구'는 어떨까? 이건 의외로 100점의 반대편인 0점이나 절반인 50점을 뜻하는 게 아니다. 인간이 신이 아닌 이상, 미래에 일어날 일을 단정적으로 예측할 수 없고 무조건 100%라고는 차마 말할 수 없으니까 90, 99 내지 99.9%라는 뉘앙스를 담아서.. 저건 '거의 사실상 영구적인'이라는 뜻이다. "이 기계는 정비 없이 반영구적으로 사용 가능합니다"처럼 말이다.

그도 그럴 것이 '영구, 영원'이라는 건 수학적으로 봤을 때 무한을 나타낸다. 그런데 무한대는 반으로 나눠 봤자 여전히 무한대일 테니, '반영구'도 뜻이 저렇게 될 수밖에 없겠다.
'반영구'와 비슷한 방식으로 개인적으로 의아함을 느꼈던 단어가 영어에도 있는데.. 바로 depress이다.
de-에는 잘 알다시피 반대 역행(decode), 제거(defrag, deice..), 감소(decrease) 등의 뜻이 있다.

그러니 depress가 의기소침, 우울, 불경기, 불황 등의 뜻이 담긴 동사인 것은 이해가 되지만.. 이것 자체에도 press와 별 차이 없는 "버튼, 페달 따위를 누르다"라는 중립· 물리적인 뜻도 있는 것은 의외인 것 같다. 마치 반영구와 영구가 뜻이 별 차이가 없는 것처럼 말이다. 자동차 운전석에서 특정 페달을 밟는 동작도 depress로 표현 가능하다.

re-가 붙어서 원래 단어와 별 차이 없거나 강조 뉘앙스가 담긴 다른 뜻이 되는 경우가 있는 것처럼.. (예: avenge-revenge, award-reward, plenish-replenish)
de-도 비슷한 작용을 한 건가 싶은 생각이 든다. liberate - deliberate, light - delight도 둘이 서로 반의어 관계는 아니니 말이다.

2. 크다/작다, 많다/적다

'크다/작다'(대소)와 '많다/적다'(다소)는 직관적인 것 같으면서도 의외로 언어 차원에서 엄밀한 구분이 쉽지 않은 개념이다.

(1) 먼저, 이산적이고 양자화되어 수효를 셀 수 있는 디지털 개체에 대해서는 자연스럽게 ‘많다/적다 many/few’가 쓰인다. 사람이라든가 자동차 등.. 영어라면 이런 개체가 하나만 존재할 때는 부정관사 a가 붙을 수 있다.

(2) 이와 달리, 단일 개체에 대해서 시각적인 size를 논할 때는 ‘크다/작다’가 쓰인다. 영어로는 large/small, big/little 같은 단어 쌍이 있으며, 이 외에도 great, huge, tiny 같은 단어도 있어서 표현이 다양하다. 사람의 키, 건물의 높이에 대해서는 tall도 쓰인다.

(3) 각각의 개수를 셀 수 없는 아날로그스러운 물질.. 가령 액체 기체 같은 유체에 대해서는 수가 아니라 양(부피)이 많거나 적다고 말한다. 한국어로는 표현이 동일하지만 영어는 잘 알다시피 much/little을 사용한다.
이거 경계가 좀 모호한 편이다. 고체의 경우, 사람의 머리카락이나 쌀알, 콩알은 1자리 단위의 개수를 세는 게 무의미하고 양만을 측정하긴 하지만 그래도 many가 쓰이는 듯하다. 모래알이나 흙 정도는 돼야 much가 된다.

(4) 그리고 애초에 형태가 존재하지 않는 사랑, 근성, 노력 같은 건 당연히 셀 수 없는 개념들이다. 영어로는 응당 much/little이 쓰이지만.. 우리말은 둘의 구분이 막 엄격하지 않고 ‘많은 사랑, 큰 사랑’ 다 집어넣어도 말이 되는 것 같다. 하긴, 영어로도 great와 much를 생각해 보면 ‘크다’와 ‘많다’가 모두 가능한 듯하다.

(5) 끝으로, 많고 적음을 나타낼 때 숫자가 쓰이기는 하지만, 숫자의값 자체는 크거나 작다고 수식한다. 이것을 영어로는 great/little이라고 하며, 비교급은 greater/less이다. 이건 시각적인 크기를 나타내는 (2)와 표현은 비슷해도 관점은 약간 다르다고 봐야 할 것이다.

이런 이유 때문에 수와 양의 구분이 분명치 않고 메롱인 상황에서는 ‘적다/작다’도 덩달아 헷갈리게 된다.
영어의 little은 가산명사와 불가산명사에 대해서 뜻이 너무 다양하게 함축적으로 많이 들어있는 것 같다. 심지어 little과 少에는 ‘어리다’라는 뜻도 들어있다.

3. 동물 명칭

한국어에는 가축 급의 친숙한 동물 몇 종에 대해서..
말-망아지, 소-송아지, 개-강아지 이렇게 짤막한 총칭에다가 접사 '-아지'가 붙어서 그 품종의 어린 새끼를 가리키는 패턴이 존재한다. 신기하지 않은가?

그런데 옛날에 원래는 '돼지'도 저런 관계였다고 한다. 돼지를 가리키는 총칭은 '돝'...;;; 이었고, 새끼돼지를 '도야지'라고 불렀는데.. '돝'이라고만 해서는 변별이 잘 안 됐나 보다. 나중엔 '도야지'가 돼지의 총칭이 되고 음운이 축약되어 오늘날의 '돼지'로 정착했다. 오늘날은 '도야지'는 돼지의 방언 내지 귀여운 별칭 정도로나 여겨지고 있다.

사실, '돝'은 너무 짧아서 돛도 아니고 dot도 아닌 것이 좀 난감하긴 해 보인다. 먼 옛날의 한국어에는 지금보다 모음 양 옆(음절초나 음절말)에 여러 미세한 자음들이 붙는 게 더 자연스러웠는가 보다.
'돝' 말고도 저렇게 짤막한 단어가 현대에는 더 길어지고 늘어난 게 내가 정확하게 기억은 안 나지만 여럿 더 있다. 참고로 나무 열매 '도토리'도 '돝'에서 유래되었으며, 다람쥐뿐만 아니라 돼지 역시 도토리를 아주 좋아한다고 한다.

아울러,

  • '돝'에서 음운이 더 탈락해서.. 윷놀이에서 말을 한 칸만 움직이는 명칭인 '도'도 돼지의 흔적이다.
  • '-아지'와 비슷한 역할을 하는 접사가 영어에는 '-ling'(저글링;;)이나 '-ette'(디스켓) 정도 있는데, 이들도 막 활발하게 생산성이 있어 보이지는 않는다.
  • 영어는 소와 돼지에 대해서 해당 동물의 '고기'를 가리키는 단어가 별도로 존재한다. pork, beef... 그리고 몇몇 고양잇과 동물의 새끼를 총칭하는 cub라는 단어가 있는데, 한국어는 딱히 그에 대응하는 개념이 없다.
  • 닭의 새끼인 '병아리'는 도대체 어디에서 유래됐는지 '닭'하고는 관계가 전혀 억고, '-아지'하고도 완전히 같지는 않은 게 인상적이다.

4. 천둥, 번개, 벼락

천둥, 번개, 벼락은 동일한 기상 현상에서 유래된 단어이며 모두 ‘-(내리)치다’가 붙을 수 있는 대상이다. 별 구분 없이 섞여 쓰이는 경향도 있다. 하지만 이들은 묘사하는 관점이 원래 서로 제각기 다르다. 마치 열차, 기차, 전철, 철도 등의 뒤죽박죽 단어처럼 말이다.

  • 천둥: 쿠구궁~~ 콰르릉 같은 엄청나게 크고 우렁찬 소리를 가리킨다(청각). ‘天動’이라는 한자어에서 유래되었으며, 원래 순우리말은 ‘우레’이다. 우뢰가 아님. 아마 한자 뢰(雷)의 영향으로 말이 바뀌는 것이지 싶다. 영어로는 thunder이다.
  • 번개: 구름과 구름, 또는 구름과 대지 사이에 전기 방전이 일어나서 번쩍이는 그 직선 모양의 불꽃을 가리킨다(시각). 번갯불, 번개 모양 아이콘/아이템 등의 형태로 쓰이며, 비유적으로는 몹시 빠르고 날쌘 것을 가리키기도 한다. 영어로는 lightning이다.
  • 벼락: 번개와 비슷하지만.. 특별히 번개가 떨어져서 지면에 닿는 현상을 가리킨다(낙뢰?). 그러니 천둥 번개가 비교적 중립적인 심상인 반면, 얘는 “벼락 맞아 뒈지라”, “마른 하늘에 날벼락”처럼 인적· 물적 피해를 동반하는 부정적인 심상이 강하다. 청천벽력이라는 한자어에서 유래되었다(벽력). 영어로는 thunderbolt에 가깝다.

현실에서는 광속과 음속의 차이로 인해 번개 비주얼과 천둥 소리가 동시에 발생하지도 않는다. 그래서 같은 현상에서 유래되었지만 언어 차원에서 둘을 더욱 분리해서 별개로 생각하게 된 것 같다. 다만, 번개와 벼락의 구분은 한국어에 좀 독특하게 존재하는 것으로 보인다.

5. 접사 '호'

한국어는 선박을 여성형 대명사로 가리키며 모에화(...)하지는 않지만, 선박의 이름 뒤에 꼭 '-호'라는 접사를 붙이는 관행이 있다.

-호 (號) [접미사] 배· 비행기· 기차 따위의 이름에 붙여 쓰는 말. (표준 국어 대사전)


이건 받침 있는 사람 이름 뒤에 붙는 잉여 접사 '-이'(복순이, 갑돌이)하고도 물론 같지는 않지만 좀 비슷한 구석이 있지 않나 생각된다.
순서를 나타내는 1호, 2호(의존명사) 내지 창간호 따위의 '호'와는 성격이 명백히 다름을 유의하시라.

옛날에는 사람이 타는 교통수단이란 게 매우 희귀하고 수가 적고 신기한 물건이었다. 그렇기 때문에 각각의 개체가 이름이 붙고 고유명사화· 인격화되곤 했다.
과거의 우리나라 열차 이름 해방자호, 융희호 따위는 해당 열차 등급이 아니라 특정 차량의 명칭에서 유래됐다.
심지어 1950년대에는 여객기에도 각각의 기체에다 만송호, 창량호, 우남호 같은 이름이 붙었을 정도였다. (꼴랑 세 기..)

하지만 세월이 흐르고 작명 방식에도 한자어가 아닌 영어물이 들면서 이런 '-호' 관행은 쓰이지 않게 됐다. KTX호, ITX-청춘호 이러지는 않으니 말이다.
오로지 선박만이 각각의 선체에다가 이름을 붙이는 관행과 함께 '-호'가 여전히 현역인 것 같다. 심지어 거기는 외래어 명칭 뒤에도 '-호'가 잘만 붙는다.

스포츠 신문에서는 운동 선수들이 감독과 함께 한 배를 탔다는 걸 비유하고 싶어서인지 '히딩크호, 허정무호 순조롭게 출항' 이런 말을 쓰는 경우가 있다.
그리고 '나로호'는.. 열차도, 선박도 아니고 우주 로켓임에도 불구하고 어째 '-호'가 자연스럽게 붙었다. 이 21세기에도 '-호' 네이밍이 완전히 죽지는 않은 듯하다.

다만, 이런 저런 정황을 감안하다 하더라도 옛날에 태풍 이름에도 '-호'가 붙은 건 아무리 생각해도 의아하다. 대표적으로 1959년의 그 악명 높았던 태풍 '사라호' 말이다. 태풍은 그냥 자연 현상일 뿐, 인간이 개발한 교통수단이나 발명품이 전혀 아닌데..?
그때는 태풍더러 좀 순해지고 피해를 덜 끼치라고 국제적으로 여성 이름이 붙던 시절이었다(1979년까지).. 이 '사라'는 실제 여성 인물을 가리키는 게 아니라는 뜻에서 '-호'가 추가된 걸까? 알 수 없는 노릇이다.

Posted by 사무엘

2021/05/27 08:34 2021/05/27 08:34
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1892

컴퓨터 소프트웨어계에는 이미 작성되어 있는 프로그램을 실제로 돌려 보지 않고(샌드박스 가상 머신 안에서..) 형태만 들여다보고는 버퍼 오버런이나 메모리 누출 같은 잠재적 위험성 및 논리 결함을 어느 정도 찾아 주는 '정적 분석'이라는 기술이 존재한다. 그 프로그램이 기계어 바이너리 형태이건, 고급 언어 소스 코드이건 형태는 무엇이건 상관없다.

그런데 정적 분석 툴은 그 누가 만든 것이라도 원천적으로 이론적으로 근본적으로 100% 정확하게 작동하지는 못한다.
이에 대해서 "아니 소스 코드가 무슨 자유 의지를 지닌 생명체도 아닌데 그 뻔한 로직을 분석해서 결과를 사전 예측하는 게 그렇게 어려운가? 단순히 소모하는 메모리와 계산량만 많아서 어려운 거라면 컴퓨터의 성능빨로 극복 가능하지 않은가? AI 기술을 접목하면 되지 않는가?" 처럼 생각하기 쉽다.

하지만 그렇지 않다. 그 말은 저런 차원이 아니다.
그런 함수는 단순히 현실적으로 구현하기가 어려운 정도가 아니라 논리 차원에서 모순에 빠지며 존재 불가능하기 때문이다. "모든 창을 막는 방패와 모든 방패를 뚫는 창 세트"와 동급으로 존재 불가능하다~! 창이나 방패의 제조 기술과는 무관하게 말이다.

가장~~ 원초적인 정적 분석 프로그램을 생각해 보기로 한다.
분석할 대상인 프로그램 코드, 그리고 그 프로그램에다가 넘겨줄 입력 데이터.
이 둘을 인자로 받아서 이 프로그램의 시시콜콜한 무슨 메모리 문제 따위를 진단하는 게 아니라..
이 프로그램이 무한 루프에 빠지지 않고 실행이 종료되기는 할지를 정확하게 판단해 주는 bool DoesThisProgramReturn(func, argument) 라는 가상의 함수 프로그램을 생각해 보자.

argument는 현실의 프로그램으로 치자면 명령 인자뿐만 아니라 프로그램이 파일이나 네트워크 형태로 읽어들이는 방대한 입력 데이터까지 모두 포함하는 개념이다. "일괄 처리 형태가 아니라 입출력이 실시간으로 들어오는 프로그램은요?" 이건 이 시점에서 그리 중요한 문제가 아니니 논외로 한다.
func는 뭐.. C/C++로 치면 기계어 코드를 가리키는 함수 포인터 정도로 생각하면 이해하기 편하겠다.

당연한 말이지만 저 함수 자체는 절대로 무한 루프에 빠지지 않고 언제나 유한 시간 안에 답이 나오는 게 보장된다. 무한 루프에 빠지는 프로그램을 의뢰했더라도 말이다. 그러므로 DoesThisProgramReturn(DoesThisProgramReturn, xxx)는 xxx로 무엇을 넘겨주건 그 정의상 리턴값이 언제나 true가 된다.

그럼.. 저 가상의 함수는 어떤 식으로 동작할지를 생각해 보자.
func가 가리키는 코드를 읽으면서 while(true); 같은 패턴을 발견한다거나,
더 구체적으로는 예전에 한번 거쳤던 state와 동일한 state로 이미 지났던 지점을 또 지나는 게 감지되면.. 이 프로그램은 실행이 끝나지 않는다는 결론을 내릴 수 있을 것이다.

이거 만델브로트(망델브로) 집합을 그릴 때 주어진 복소수의 발산 여부를 판별하는 것과 비슷하게 느껴진다.
배배 꼬인 복잡한 프로그램에서는 좀 어렵겠지만 그래도 도저히 불가능한 문제는 아니어 보이는데..??

하지만 튜링 기계는 우리가 흔히 생각하는 것보다 자유도가 더 높은 계산 모델이다.
메모리에 저장된 주소값에 해당하는 다른 메모리의 값을 마음대로 읽고 쓸 수 있을 뿐만 아니라(= 포인터) 거기 저장된 데이터를 코드로 간주해서 실행할 수도 있다(= 함수 포인터).

재귀 호출도 되고.. 또 앞서 살펴보았듯이 DoesThisProgramReturn 자신조차도 튜링 기계에서 실행되는 함수이기 때문에 DoesThisProgramReturn의 인자로 전달할 수 있다. 그리고 분석 대상인 타 함수가 얘를 또 호출할 수도 있다.
이런 상황까지 다 허용 가능해야 한다면 DoesThisProgramReturn의 존재 가능성은 굉장히 난감해진다.

아래와 같이.. DoesThisProgramReturn가 true라고 판정한(= 실행이 끝난다) func에 대해서는 "반대로" 자신이 무한 루프로 가 버리고, 실행이 끝나지 않는 함수에 대해서는 실행을 끝내는 HangIfReturns이라는 함수를 정의해 보자.

bool HangIfReturns(func) {
    if (DoesThisProgramReturn(func, func)) while(true);
    return true;
}

그러니 HangIfReturns(DoesThisProgramReturn)을 하면.. 얘는 무한 루프에 빠지게 된다.
DoesThisProgramReturn은 자기 자신에 대해서는 앞서 정의한 바와 같이 언제나 true를 되돌리고(= 늘 깔끔하게 실행 종료) if문을 만족하기 때문이다. 여기까지는 쉽다.

하지만 반대로 HangIfReturns가 DoesThisProgramReturn의 인자로 들어가면 어떤 일이 벌어질까? DoesThisProgramReturn(HangIfReturns, HangIfReturns)는 리턴값이 무엇이 되는 게 이치에 맞을까? 이제 좀 머리가 복잡해질 것이다.

DoesThisProgramReturn(HangIfReturns, HangIfReturns)가 true라면.. HangIfReturns 안의 if문은 true가 되므로 HangIfReturns은 무한 루프에 빠진다. 그러면 저 함수의 리턴값은 원래 false가 되어야 하게 된다.
반대로 저 리턴값이 false라면.. 역시 이제 HangIfReturns는 실행이 깔끔하게 종료되므로 저 함수의 리턴값을 정면으로 부정하는 결과가 나온다.

요컨대 HangIfReturns가 무한 루프에 빠지는지의 여부는 DoesThisProgramReturn의 리턴값에 따라 달라지는데, 이 과정에서 서로 물고 무는 구조적인 모순이 발생하는 셈이다.
이 모순은 DoesThisProgramReturn라는 함수가 존재한다는 가정으로부터 비롯되었다. 그러니 튜링 기계 하에서 다른 코드의 실행 종료 여부를 완벽하게 판단하는 코드를 똑같은 튜링 기계 기반으로 구현하는 것은 불가능하다는 것이 입증된다.

이 논리는 "정지 문제"(halting problem)이라고 불리며, 컴퓨터라는 기계의 계산 가능 범위를 고민하게 하는 매우 탁월한 통찰이다. 이걸 처음으로 생각해서 논문으로 발표한 사람이 바로 그 이름도 유명한 앨런 튜링이다.

과학 철학에서 "반증 가능한가", 천문학에서 "관측 가능한가"처럼.. 전산학에서는 "계산 가능한가, 튜링 기계를 돌려서 답을 구할 수 있는 문제인가"가 중요한 고민거리가 된다. 계산 자체가 이론적으로 가능해야 그 다음 관심사는 "실용적으로 유의미한 시간 만에 빨리 해결할 수 있는가?", 더 구체적으로는 "입력 크기 N에 관한 다항식 급의 시간 안에 해결 가능한가 (팩토리얼이나 지수 함수 급이 아니라)"라는 시간 복잡도가 될 것이다.

TSP(순회하는 세일즈맨) 문제 같은 NP-완전 문제는 이론적으로 알려진 시간 복잡도가 너무 높기 때문에 실생활에서는 적당히 성능이 좋은 다항 시간 근사 알고리즘이 쓰인다.
그래도 정지 문제는 3-SAT 문제라든가 NP-완전처럼 시간 복잡도를 따지는 증명보다는 덜 난해하고 직관적인 설명도 가능하기 때문에 수식 없이 블로그에다 증명 방식을 소개도 할 수 있다. 현실에서는 논리적으로 100% 완벽하고 헛점이 없고 100% 정확하게 동작하지는 못하지만 그래도 현실적으로 충분히 정확하고 속도도 적절한 각종 소스 코드 정적 분석 기능이 개발되어 쓰이고 있다.

Posted by 사무엘

2021/05/24 19:36 2021/05/24 19:36
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1891

5 16과 5 18

1. 군사혁명

사용자 삽입 이미지

이건 우리나라의 역사를 크게 바꿔 놓은 혁명이었다. 저 우표가 나왔던 때는 당해(1개월), 그리고 1주년이었는데.. 올해는 무려 60주년이다.

원조가카는 그 암울하던 시절에 어째 자기 목을 걸고 저렇게 나라를 뒤엎어서 통째로 마개조할 생각을 했는지.. 가히 또라이 그 자체였다. 10여 년 뒤엔 이걸로도 모자라서 유신이라는 것까지 만들어 내고..
할배는 자기가 물러난 이후로 웬 미친 후계자가 갑툭튀해서 그래도 선한 독재를 하고 있는 걸 하와이에서 인지할 기회는 있었나 모르겠다.

10수 년 전부터 해 온 생각이지만, 할배는 정말 모세 같다. (넘사벽급의 위대한 초대 지도자. 홍해 -- 원자탄, 타지에서 죽음)
원조가카는 느헤미야(느 4:17, 일하면서 싸우고 싸우면서 일하고..)나 웃시야 왕(대하 26. 영농과 국방 개혁, 기계 제조) 같다.

박 정희 시절부터 사회 시스템이 바뀐 것 중 하나가 단기 대신 서기 연호이다. 그래서 당장 저 우표만 봐도 1961년에 나온 첫 버전은 날짜가 단기로 표기된 반면, 1주년 기념 우표는 서기 표기이다.

사용자 삽입 이미지

그리고 우리나라 근현대사에서 빼놓을 수 없는 중요한 사진 중 하나가 바로 이거다. 자유당 시절의 정치 깡패들이 서울 시내에서 공개 조리돌림 당하는 거. "나는 깡패입니다. 국민의 심판을 받겠습니다" =_=;;

특히 다른 깡패들은 여럿이 뭉쳐서 퍼레이드(?)를 했지만, 수괴이던 이 정재는 단독으로 제일 앞장서서 가면서 개쪽을 당해야 했다.
옆에 감시하는 사람들은 경찰도 아니고 무려 특수부대 급의 군인이었다. 알고 보니 이것 말고 다른 각도와 시점에서 찍은 사진도 여럿 전해진다.. 오오~

대한민국에서 1948년 건국 이래로 공권력에 의해 공개 조리돌림이 행해진 건 이게 유일하다. 우리나라 역사상 살인 없이 연쇄 강간만으로 사형이 선고된 건 5공 시절이 유일했듯이 말이다.
이때가 혁명일로부터 겨우 닷새 뒤인 1961년 5월 21일이었다는 것도 같이 알아 두면 좋다. 요즘은 악질 음주운전 사고 가해자나 아동 학대치사 살인범을 이런 방식으로 죄값을 좀 치르게 했으면 좋겠다.

2. 광주 사태

1980년대 노래 중에서 '바위섬'이라는 유명한 노래가 있다. 얘는 벧후 3:5-6의 without form and void 분위기를 온몸으로 외치는 노래 같다.

  • 파도가 부서지는 바위섬 인적 없던 이 곳에
    (==> 하늘들이 옛적부터 있었고 또 땅이 물에서 나와 물 가운데 서 있는 것을)
  • 어느 밤 폭풍우에 휘말려 모두 사라지고
    (==> 그때 있던 세상은 물의 넘침으로 멸망하였으되)

성경에 창 1:1과 1:2 사이에 정말 엄청난 일이 있었던 것처럼, 저 노래도 사실은 정말 엄청난 과거 사건을 모티브로 삼아서 만들어진 거라고 한다.
그럴싸해 보이지 않는가? 언젯적부터 해 온 오래된 생각인지 기억조차 가물가물하다.

5월 16일로부터 겨우 이틀 뒤는 어째 16하고는 이념적으로 완전히 딴판인 기념일이다. 이 날에 대한 나의 생각은 이렇다.

  • 소수의 북괴 공작원이 시민을 사칭하면서 진짜 시민과 군경 사이를 이간질하고 서로 오해하게 만들고, 약간만 대립하고 끝났을 사건을 악에 받친 유혈 참극으로 도지게 만들었을 가능성은 있음.
    (진실을 규명하려면 이런 거나 규명해야 하는데, 인제 와서 규명이 제대로 될 가능성은 거의 없음. 참고로 1980년대 초는 무장공비가 활발하게 드나들었으며, 동해 서해의 남부 지방까지 막 침투하고 잡히기도 하던 시절이었음.)

  • 누구 말처럼 600명씩이나 침투는 가능하지 않음. 6 25 초반의 대한해협 해전 때의 북괴 공작원의 침투 규모하고 딱 혼동한 것 같다.
    더 옛날에 북쪽에 더 가깝게 침투했던 울진-삼척 무장공비도 100여 명에 불과했고, 그것도 여러 차례 나뉘어서 침투한 것이었다.

  • 안면인식으로 30여 년 전의 광수 찾는 건 너무 심한 뱀발 무리수

  • 무기고 탈취와 탱크 조종, 능수능란한 군사 활동 자체만으로는 북괴 공작이라고 전혀 간주할 수 없음.
    저 땐 남한도 남자들이 군사 독재 하에서 군복무를 3년씩이나 강제로 했었다. 훗날 LA 폭동 때도 군대에서 배운 게 제대로 발휘됐다니까?

  • 북괴에서 띄워주고 선전한다고 해서 그게 반드시 자신과 관계 있는 사건이라는 보장도 없음.
    아웅산 테러 공작원의 존재는 생까고, 효순이 미선이한테는 평양 학교 명예 학생 임명도 하고 저런다. 이것 말고 다른 일관성 없는 반례는 얼마든지 있다.

그러니,

  • 시민군들이 몽땅 북괴 공작원 빨갱이라는 소리나, 그 반대 극단으로 진압군이 멀쩡한 비무장 시민들 가슴을 도려내고 싸이코패스마냥 총질했다는 소리는 거의 다 신빙성이 결여되는 과장 거짓이라 여겨진다. 악의적이거나, 아니면 너무 오래돼서 기억이 왜곡됐거나.
  • 도를 넘는 성역화, 그리고 반대로 도를 넘는 폄하와 비하 모두 금물. 시민 희생자를 추모할 거면 진압 군경 전사/순직자도 같이 추모해야 한다.
  • 김 일성이건 전땅크건 회고록은 공평하게 다 출간하면 된다.

그리고 무엇보다 중요한 것은..
광주 사태가 진짜로 전대갈의 쿠데타에만 반대하고 항거하는 민주화(?) 시위였다 하더라도 그건 나라를 북괴 침략으로부터 지키고 가난을 떨쳐낸 것보다 더 중요하고 시급하고 위대한 업적은 절대 아니라는 것이다.
파급력과 영향력을 따지자면 4 19 의거보다도 가중치가 더 낮다. 그냥 제주 4 3 사태나 박통 말기의 부마 항쟁 이런 것보다 급을 높게 쳐야 할 이유를 난 모르겠다.

그런데 지들이 뭐 나라를 구하기라도 한 줄 알아요. 유공자 생색 제일 많이 내고.. 뭐? 5 18 왜곡 금지법??
이딴 식으로 나오니 그때 정말로 억울하게 무고하게 오인 사격으로 죽었을 수도 있는 광주 시민을 같은 대한민국 국민으로서 추모하고 기리고 싶은 생각마저도 싹~~ 사라지게 된다.

나도 망망대해 위에 솟은 바위섬 꼭대기에서 밤에 텐트 치고 코딩 하다가 자 보고 싶다~
그리고 저 노래의 모티브인 동네는 구질구질한 피해의식 반골기질 좀 버리고(모든 사람이 그렇다는 건 물론 아님) 건전한 생각과 의식으로 "재창조" 됐으면 좋겠다.

Posted by 사무엘

2021/05/22 08:36 2021/05/22 08:36
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1890

1. 비트 연산 관련 버그

프로그래머가 살면서 설마 컴파일러의 버그를 볼 일이 얼마나 될까? 이건 마치 버스· 트럭· 택시 등 운전으로 먹고 사는 기사 아저씨가 잘 가다가 차량의 엔진 결함이나 급발진을 경험하는 것만큼이나 끔찍한 경험일 것이다.

본인은 최적화 옵션을 빡세게 주고 나면 Visual C++ 컴파일러가 비트 연산 쪽으로 유난히도 말귀를 못 알아먹는 현상을 종종 목격했다.
7년쯤 전에 VC++ 2010 기준으로 (1) bit rotate 연산을 <<, >> | 따위로 구현한 게 제대로 동작하지 않는 것을 목격했다. 그 함수만 #pragma를 줘서 최적화를 강제로 꺼야 오류가 발생하지 않았다.

그리고 2019년쯤에는 (2) WORD, BYTE 따위를 비슷한 연산으로 한데 합쳐서 DWORD를 만들려고 했는데.. 이것도 변수 내용을 강제로 로그를 찍으면 문제가 없지만 간단하게 값만 되돌리게 하면 틀린 값이 돌아왔다.
인라인 함수, 매크로 함수, 최적화 강제 해제 등 별별 방법을 써도 소용없어서 결국은 무식하게 memcpy로 값을 오프셋별로 강제 복사해서 문제를 회피해야 했다.

그 뒤, 19.5.x급으로 그 당시로서는 최신 업데이트가 적용됐던 Visual C++ 2019에서 더욱 황당한 일을 겪었다.
내가 하고 싶은 일은 8비트 char 값을 그대로 부호 없는 형태로만 바꿔서.. 즉, -3을 253으로만 바꾼 뒤 다른 산술 연산 처리를 하는 것이었다. 그런데 (3) 컴파일러가 말귀를 못 알아듣고 숫자를 32비트로 취급하면서 앞에 0xFFFFFF00를 제멋대로 붙였다.

숫자는 내가 기대한 것보다 엄청나게 큰 값으로 바뀌었으며, 프로그램은 이 때문에 오프셋 계산을 잘못해서 메모리 오류가 발생했다. 내가 아무리 강제 형변환 연산을 집어넣어 줘도 오류는 없어지지 않았다. 계산값에다가 원래는 할 필요가 없는 &0xFF 필터링을 강제로 하거나, 이 역시 최적화를 꺼야만 오류가 사라졌다. 이런..

이 세 사례는 모두 비트 연산 + 최적화와 관련된 컴파일러의 난독증이라는 공통점이 있었다. 2010으로 32비트 코드를 빌드하던 시절이나, 2019로 64비트 코드를 빌드하던 시절이나 마찬가지이니.. 딱히 버전과 아키텍처를 가리지도 않는 것 같다.

더 자세한 정황을 나열하지 못하는 이유는 이것들이 전부 방대한 회사의 코드를 취급하다가 발생한 일이기 때문이다. 그래서 동일 문제를 재연할 수 있는 최소한의 케이스를 따로 분리할 수가 없다. 그 함수만 텅 빈 프로젝트에다가 떼어내서 돌리면 당연히 문제가 발생하지 않는다.
하지만 동일 코드를 사용하여 macOS, 안드로이드 등 타 플랫폼에서 돌아가는 제품에서는 버그가 발생하지 않으니 이건 일단 Visual C++만의 문제라고 봐야 할 듯하다.

2. UTF-8 지원 여부와 미스터리한 오동작

Windows는 전통적으로 ANSI 인코딩(?) 천국이던 운영체제였다. 그래서 유니코드 자체는 진작부터 지원했지만 UCS-2 내지 UTF-16 같은 별도의 2바이트 단위 인코딩 형태로만 지원하는 것을 선호했다. 1바이트 단위 인코딩인 UTF-8의 형태로 지원하는 것에는 대단히 보수적이고 인색했다.

오죽했으면 Visual C++이 취급하는 리소스 스크립트 *.rc라든가 resource.h의 기본 포맷도 유니코드 기반으로 바뀌긴 했는데.. UTF-8이 아니라 UTF-16으로 바뀌었다. 거 참..

그래도 세월이 흐르니 마소에서도 대세를 거스를 수 없는지라, 명령 프롬프트에서 제한적이나마 65001 UTF-8 코드 페이지를 지원하기 시작했다. Windows 10 19xx 버전부터는 메모장이 기본으로 지정하는 텍스트 저장 인코딩이 UTF-8로 바뀌기도 했다.
심지어 Visual C++ 컴파일러 역시 UTF-8 인코딩의 소스 코드를 인식하기 시작했다. 단...!! 이건 2% 부족한 아쉬운 면모가 좀 있다.

바로.. 파일 앞부분에 BOM이 있을 때만 UTF-8로 인식한다는 것이다. 그렇지 않으면 그냥 ANSI이다.
소스 코드의 인코딩을 강제로 지정하는 옵션이 소스 코드 내부에 #pragma 같은 형태로 좀 있었으면 좋겠지만 그렇지는 않다. #pragma code_page라는 게 있긴 한데, C 문법을 일부 빌려 온 리소스 스크립트에만 쓰인다.
파일 내부 대신, 컴파일러의 옵션으로 /source-charset:utf-8 요런 게 존재하고, 줄여서 그냥 /utf-8이라고만 해도 된다.

생각해 보면 설정이 하나만 있는 것으로 충분하지 않다. 소스 코드 자체는 인코딩이 UTF-8인데 그 안에서 L로 둘러싸이지 않은 "한글"이라는 문자열 리터럴은 KS X 1001로, 즉 길이가 4바이트이고 전체 크기가 5바이트인 문자열을 의도한 것일 수 있다. 그렇게 실제로 의도된 인코딩을 지정하는 옵션은 /execution-charset이라고 따로 있으며, /utf-8은 두 charset을 모두 utf-8로 지정한 것과 같은 효과를 낸다.

그런데 컴파일러는 그렇게 인식시키면 되지만 에디터의 동작에 여전히 함정이 남아 있다.
BOM도 없고 딱히 한글· 한자 같은 문자도 없이 모든 문자열이 간단한 1바이트 숫자· 알파벳 따위로만 구성된 평범한 파일의 경우, Visual Studio IDE는 얘를 기본적으로 ANSI 인코딩 파일로 간주한다. 그 파일에 나중에 한글· 한자가 부주의하게 추가된다면 인코딩이 영락없이 잘못 지정될 수 있다. 이 기본 동작을 고치는 방법이 있는지는 난 아직 모르겠다.

그런데 그렇다고 BOM을 넣어 버리면..?? BOM은 Windows 동네에서나 통용되지, 리눅스 등 타 운영체제에서는 그냥 민폐 덩어리인 문자이다. 소스 파일의 앞에 저런 문자가 떡 있으면 컴파일러가 잘못 먹고 체하는 수가 있다.
그러니 한 소스를 여러 플랫폼에서 공유하는 경우, 모든 코드의 인코딩은 그냥 닥치고 BOM 없는 UTF-8로 통일하는 게 안전하다. 이 문제에 관한 한은 Visual C++이 타 빌드 툴들의 표준 관행에 맞춰 줘야 한다. BOM는 이식성을 저해하기 때문이다.

모종의 이유로 인해 Visual C++에서 소스 코드의 인코딩이 잘못 인식되면 빌드 과정에서 깨진 문자가 있다고 C4819라는 경고가 발생한다. 깨진 문자가 주석 내지 조건부 컴파일에 걸려서 어차피 빌드되지 않는 영역에 있을 때는 저게 딱히 문제될 게 없다. 단지, 문자열 리터럴 내부에 들어있던 한글· 한자가 깨지면 심각한 문제가 될 것이다.

그런데 내 경험상.. 주 번역 단위에 해당하는 소스 파일과, 걔가 인클루드 하는 헤더 파일 간에 인코딩이 다를 때도 상당히 골치 아픈 문제가 발생하곤 했다.
C4819 말고도 C4828이라고 파일의 줄 수가 아닌 오프셋 운운하면서 굉장히 기괴한 경고가 떴다. 최신 컴파일러에서는 이 경고가 삭제되었는지 조회되지도 않더라.

그리고 정말 믿을 수 없지만 컴파일러가 완전히 뜬금없는 에러를 내면서 동작을 멈췄다. 실제로 문법 오류가 전혀 없는 구문에서도 쓸데없는 에러가 발생했으며, 그 소스 파일에 실제로 존재하지 않는 칸 번호를 언급하기도 했다.
이렇게만 말하는 나도 황당하고 읽는 분들도 상황을 받아들이지 못하시겠지만.. 내가 실제로 겪은 상황이 저랬다.

이 역시 회사에서만 겪었기 때문에 정확· 엄밀하게 재연 케이스를 만들지는 못하겠다. 아까 얘기했듯이 (1) /utf-8 옵션을 global하게 준 상태에서 소스와 헤더 파일들의 인코딩이 충돌 난 것, 그리고 아마도 (2) precompiled 헤더를 쓰는 소스와 그렇지 않은 소스가 한 프로젝트 안에서 좀 뒤섞여 있는 것, (3) namespace와 using이 좀 복잡하게 얽혀서 인텔리센스도 오락가락 하는 상황인 것이 다 조금씩 영향을 주지 않았을까 생각된다.

이 난국은 모든 코드의 인코딩을 BOM 없는 UTF-8로 정리하고, 모든 코드에다가 한글로 dummy string을 만들어서 Visual Studio IDE가 파일을 ANSI (cp949) 인코딩으로 잘못 저장하는 일이 없게 조치를 취함으로써 해결되긴 했지만..
그때 그 문제가 왜 발생했으며 그 상황을 어떻게 재연할 수 있는지는 모른 채 미스터리로 남게 되었다.

회사에서는 길지 않은 기간 동안에도 이 정도의 이상한 버그를 몇 차례 경험했는데.. 개인적으로 날개셋 한글 입력기를 20여 년 가까이 만들어 온 동안은 컴파일러의 버그를 경험한 적이 거의 없다는 것이 참 신기하다. IDE야 불필요하게 다운되거나 뻗는 버그를 여럿 경험했지만 컴파일러가 문제를 일으킨 적은 없었다.
모든 코드가 깔끔하게 KS X 1001 레거시 인코딩이고, 회사 코드보다는 규모가 작고 모듈 구조가 깔끔하고, 전부 precompiled 헤더를 사용하기 때문이 아닌가 생각한다.

소스 코드의 인코딩이 UTF-8이 아니거나, UTF-8이더라도 앞에 BOM이 있는 것 자체를 경고로 처리하는 건 너무 과격할까? 그리고 #include에서 경로 지정을 /가 아닌 \로 한 걸 경고로 처리하는 옵션도 있으면 좋겠다. 이런 건 Windows 환경에서나 통용되지 밖에서는 전부 민폐 에러 요인이 되기 때문이다. 본인이 직장의 공동 작업 과정에서 종종 실수했던 적도 있는 사항들이다.

3. 인텔리센스의 오동작

끝으로, 이건 실제로 생성된 exe/dll의 동작과 관계 있는 치명적인 문제는 다행히 아니지만.. Visual C++ IDE가 텍스트 에디터에서 사용하는 인텔리센스도 일부 특이한 상황에서는 말귀를 못 알아듣고 오동작할 때가 있다.

본인이 겪은 경우는 클래스(가령 A)의 선언 내부에 MFC의 DECLARE_DYNAMIC 같은 복잡한 custom 매크로를 넣은 뒤, 곧장 private/public/protected 같은 접근 권한 지정자가 나올 때이다. 그러면 인텔리센스가 그 뒤에 이어지는 멤버 및 내부 enum/class (가령 B) 따위 선언을 파싱을 제대로 못 한다. ClassView를 보면 A의 멤버 목록에 B의 멤버들이 잘못 표시되며, B 선언 이후에 등장하는 A의 진짜 멤버들은 전혀 인식되지 않는다.

ClassView뿐만 아니라 텍스트 에디터에다 불러온 소스 코드에서도 각종 경고와 에러 밑줄이 A의 멤버들이 누락된 것처럼 쭈루룩 뜬다.
그렇기 때문에 A 클래스의 구현부에서는 인텔리센스와 자동 완성, 심벌 위치 조회 같은 기능들을 활용하지 못하면서 코딩을 꽤 불편하게 해야 한다.

이런 초보적인 문제는 Visual C++ 6 ncb 시절에나 보던 게 아니었나? 왜 발생하는지 모르겠다.
최신 업데이트를 적용한 Visual C++ 2019에서도 동일하게 발생한다. 본 컴파일러가 아니라 인텔리센스 컴파일러이니 딱히 특정 Visual C++ 컴파일러 툴킷만의 문제도 아닐 것이다.

뾰족한 해결책은 없고, 인텔리센스를 헷갈리게 하는 그 문제의 매크로를 클래스 선언의 맨 앞이 아니라 맨 뒤로 옮김으로써 문제를 회피할 수 있었다. 흠...

4. 도킹 하다가 뻗음

역시 컴파일러가 아닌 IDE 얘기이고, 옛날 버전에서만 발생하는 문제이기 때문에 지금 큰 의미는 없지만..
Windows 10 19xx대 버전부터인가 Visual Studio 2013 (그리고 아마 2015도)에서 각종 문서 편집 창이나 보조 윈도우(출력, 속성, 디버그 등등)를 어디에든지 도킹을 해서 붙이면 프로그램이 뻗어 버린다.

2010이 언제부턴가 실행될 때 Microsoft.Vsa.tlb 파일이 없다는 에러를 내는 것과 비슷한 현상인 것 같다. 그래도 얘는 정상 실행은 되고 프로그램 사용에 문제가 없는 반면, 저건 창을 내 마음대로 배치할 수 없게 만들고 프로그램이 뻗기까지 하기 때문에 상당히 심각한 문제이다.
저런 단순 UI는 운영체제건 VS건 한번 만들고 나서는 고칠 일이 없는 기능일 것 같은데.. 둘 다 내부적으로 뭘 건드리길래 이런 부작용이 발생하는 걸까..??

하긴, 더 옛날엔 Visual Studio 2005도 Windows Vista에서 실행하려면 sp1에다가 Vista 지원 추가 패치까지 설치해야 겨우 돌릴 수 있었다. 아래아한글 2005와 2007도 Vista 이후의 운영체제에서 실행하려면 업데이트부터 대판 설치해야 했었으니 이런 예가 전혀 없지는 않구나.

어떤 프로그램이 후대의 운영체제에서 단순히 GUI나 외형의 glitch 정도가 발생하는 걸 넘어 아예 뻗고 실행이 안 되는 건.. 대부분 보안 강화 때문이지 싶다. 문서화되지 않고 미래에 얼마든지 달라질 수 있는 특성이나 동작에 의존하게 프로그램이 만들어진 경우야 걔의 잘못이겠지만, 흔한 경우는 아닐 것이다.

Posted by 사무엘

2021/05/19 08:35 2021/05/19 08:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1889

1.
손으로 쇠붙이를 만진 뒤에 손에서 느껴지는 쇠비린내는 평소에 손에서 분비되는 자잘한(...) 액체 물질이 철과 마주쳐서 변질되면서 나는 냄새일 뿐이다. 금속 쇠붙이 자체는 원래 그 어떤 냄새도 나지 않는다.;;
인체의 땀도 분비된 직후에는 별 냄새가 안 나다가 나중에 세균에 의해 분해되고 부패되면서 지린내가 난다. 이와 비슷한 이치이다.

2.
하품은 통념과 달리, 꼭 산소가 부족해서 발생하는 이벤트는 아니라고 한다. 인체 자체가 이산화탄소 과다에 반응하지, 산소 부족에 반응하는 구조가 아니라는 것은 주지의 사실이다.

3.
어라..? 햇빛을 맨눈으로 보고 있으면 재채기가 나는 건.. 난 하품 할 때 눈물 나는 것만큼이나 누구에게나 똑같이 발생하는 현상이라고 생각했는데 그렇지 않은가 보다. 전체 인구의 2~30%가량에서만 발견되는 현상이라니! 게다가 유전 형질 때문인지 무엇 때문에 발생하는 현상인지 아직 의학적으로 제대로 규명도 되지 않았다고 한다.
하긴, 먼 옛날 초딩 시절에 본인은 난 밝은 낮 하늘에 뭔가 알갱이, 입자 같은 게 비쳐 보이는 게 공기의 분자-_-;;;일 거라고 생각했었다. '비문증'이라는 현상이라는 걸 알게 된 건 최근의 일이다.

4.
무산소 운동을 많이 했을 때 근육이 저리고 통증이 느껴지는 것은 젖산이 분비되어서 그런 것이라고 지난 수십 년간 과학 시간에 가르쳐져 왔으나.. 더 자세히 관찰해 보니 그렇지 않다는 것이 밝혀졌다. 주변의 칼륨 이온의 농도 때문이라고..
사실, 이런 통증은 인체가 느끼는 다른 많은 고통들과 마찬가지로 몸을 망가뜨리지 않고 보호하기 위해 발동되는 경고 신호이다.

몸을 망가뜨리기 위해 굳이 근육을 무리하게 혹사시키며 운동을 하지 않아도 된다. 사람이 꼼짝도 안 하고 시체처럼 부동 자세로 오래 있으면.. 체중에 너무 오래 짓눌린 부위가 피가 잘 안 통해서 그것만으도 저림, 가려움을 느끼게 된다. 팔이나 무릎을 굽힌 부자연스러운 자세가 아니라 최대한 편하게 누워 있더라도 이런 현상을 피할 수 없다.

그러니 정상적인 사람이라면 저절로, 심지어 자는 중에도 본능적으로 몸을 수시로 뒤척이게 된다. 그런데 척수 손상 등으로 인해 하반신/전신이 마비된 사람은 이런 통증을 못 느낀다.
몸을 그대로 잘못 방치했다간 등이나 엉덩이 일부 부위에 그 이름도 무서운 욕창이란 게 생겨서 조직이 괴사해서 썩게 된다. 이런 참사를 예방하려면 간병인이 환자의 체위를 수 시간 주기로 바꿔 줘야 한다.

뭐, 단순히 신체 부위가 피가 안 통해서 저리는 것은, 처음에 얘기했던 근육통하고는 근본이 좀 다른 얘기이지만, 어쨌든 몸을 보호하려는 의도의 통증이라는 점은 동일하다. 영화 <항거>에서 형무소에 갇힌 죄수들이 일부러 방을 빙글빙글 왜 돌았는지, 그리고 사람을 벽장에다 선 채로 집어넣고 며칠 방치하는 게 그것만으로도 왜 잔인한 고문인지 이제 이해가 될 것이다.

뭔가 굉장히 희소한 병에 걸린 어떤 사람 중에는 선천적으로 통증을 전혀 못 느낀다거나, 땀을 전혀 못 흘린다거나 하는 경우가 있다. 그게 좋은 게 절대 아니다. 위험한 줄 모르고 뜨거운 물에다 손을 담그고 있다가 손을 완전히 망가뜨린다거나, 더운 곳에서 땀을 안 흘리고 있다가 그냥 픽 쓰러지고 훅 가기 때문이다.

글쎄, 무중력 상태에서는 중력이 없고 짓눌림이란 게 없으니 욕창 걱정은 안 해도 될 것 같아 보인다만.. 그건 또 완전히 다른 방식으로 인체의 생리에 좋은 상태가 아니다.

5.
살이 찌고 체중이 늘어난 것은 비록 현대의 바쁜 사무직 직장인에게 쉽지만은 않겠지만 식탐 자제하고 운동을 많이 함으로써 고칠 수 있다. 살을 빼고 체중을 줄이고, 지방 대신 근육을 늘릴 수 있다.

그러나 관절 같은 것은 운동으로 단련 가능하지 않다. 성장이 끝난 뒤부터는 일방적으로 약해지고 퇴화만 하며 부상을 입어서 다칠 위험이 커진다. 어린 시절에는 내리막을 아무렇지도 않게 빨리 내려갔는데 나이가 들면 그런 것도 함부로 하기 어려워진다.

또한, 탈모는 현대 의학으로도 불치병으로 여겨지고 있고.. 얼굴이 자외선 맞아서 검어지고 타는 것도(한자어로 한 단어가 없을까?) 마치 노화나 단백질의 열변형만큼이나 뒤로 되돌릴 수 없는 비가역 현상이다.;; 에구~ 이런 걸 생각하면 섬뜩하고 좀 후회도 된다. 있을 때 관리를 잘 했어야지..

6.
병 중에는 환자 혼자만 앓고 마는 게 아니라, 남까지 원인균이나 바이러스를 옮기기 쉬운 무서운 전염병이라는 게 있다. 그리고 그 전파 매개라는 게 생각보다 다양하다.

  • 공기: 결핵, 홍역, 천연두/수두
  • 비말: 감기, 폐렴, 코로나19!!
  • 물/음식물: 장티푸스, 콜레라, 이질
  • 접촉/체액: 에이즈, 각종 성병, 에볼라, 파상풍

도대체 병원체가 분자 수준으로 얼마나 가벼우면 공기를 타고 날아다니며 퍼질 수 있는지 궁금할 지경이다. 공기와 비말 감염을 막으려고 마스크라는 물건이 발명되어서 현재 인류 역사상 유례가 없이 많이 소비되고 있다.

그래도 지금까지 의약학과 보건 기술이 눈부시게 발달한 덕분에 요즘은 인간의 평균 수명이 크게 늘었고, 노인도 옛날처럼 이빨 빠진 꼬부랑이가 되는 게 아니라 예전보다 많이 쟁쟁하고 건강하다. 다른 전염병으로 일찍 죽지 않으니, 암이라는 더 미세하고 고차원적인 병에 걸려 죽는 빈도가 더 늘었다.
암은 최소한 전염병은 아니다.;; 그리고 세균이나 바이러스가 아니라 그냥 암 '세포'라고 부른다.

Posted by 사무엘

2021/05/17 08:37 2021/05/17 08:37
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1888

프로그래밍에서 메모리를 가리키는 포인터라는 건.. 그 특성상 돌아가는 컴퓨터의 machine word와 크기가 동일하다. 하지만 현실에서 포인터(= 메모리 주소)를 구성하는 모든 비트가 골고루 쓰이는 일은 몹시 드물었다.

먼저, 컴퓨터의 실제 메모리 양이 포인터가 가리킬 수 있는 범위보다 훨씬 적다. Windows의 경우, 32비트 시절에는 user mode에서는 대부분의 경우 포인터의 상위 비트가 언제나 0이었던 것이 잘 알려져 있다(하위 2GB까지만 사용).
하물며 64비트는 공간이 커도 너무 크기 때문에 가상 메모리 관리 차원에서도 아직은 40~48비트까지만 사용한다. 상위의 무려 16비트가량이 쓰이지 않는다는 것이다. 램이 32GB여도 겨우 35비트면 충분하니까..

가난하고 배고프던 20세기 16비트 시절에는.. 반대로 포인터 하나만으로 겨우 몇백 KB~수 MB 남짓한 메모리도 한번에 다루지 못했다. 그래서 far 포인터니 huge 포인터니 별 삽질을 다 해야 했는데 그때에 비하면 지금은 격세지감이 따로 없다.

저렇게 상위 비트뿐만 아니라 하위 비트도 마찬가지이다. padding, align 같은 이유로 인해, 메모리 할당 함수의 포인터 리턴값이 홀수가 될 일은 일반적으로 없다. 아니, 겨우 2의 배수가 아니라 4나 8의 배수가 될 수도 있으며, 이 경우 하위 2~3개 비트도 0 이외의 값을 가질 일이 없게 된다.

그러니 포인터를 저장하는 공간에서 0 이외의 값이 들어올 일이 없는 비트에다가 자신만의 정보를 넣는 꼼수를 부리는 프로그램이 예로부터 줄곧 존재해 왔다.
이거 무슨 변태 같은 짓인가 싶지만.. 이제 막 32비트로 넘어가긴 했지만 아직 가정용 컴퓨터들의 평균적인 메모리 양이 수 MB대밖에 안 됐던 시절이 있었다. 이때는 메모리가 부족해서 하드디스크 스와핑이 일상이었다. RAM을 1바이트라도 더 아끼는 최적화가 필수였다.

가령, 다재다능한 자료구조인 빨강-검정 나무를 생각해 보자.
노드의 색깔을 나타내는 겨우 1비트짜리 정보를 위해서 굳이 bool 멤버를 추가하는 건 굉장한 낭비라는 생각이 들지 않는가? 단 1비트 때문에 구조체 패딩까지 감안하면 무려 2~4바이트에 달하는 공간이 매 노드마다 허비되기 때문이다.
안 그래도 노드의 내부엔 left/right 같은 딴 노드 포인터가 있을 것이고, 포인터 내부에 쓰이지 않는 1비트 공간이 있으면 거기에다 색깔 정보를 박아 넣고 싶은 생각이 들 수밖에 없다. 비트필드와 포인터의 union 써서 말이다.

물론, 그렇게 0으로만 채워지던 공간을 운영체제에서도 나중에 유의미하게 사용하기 시작하면.. 그 꼼수 프로그램은 재앙을 맞이하게 된다.
대표적인 예로 마소에서는 32비트 기준으로 사용자:커널이 통상적인 2GB:2GB가 아니라 3GB:1GB로 주소 공간을 분할하는 기능을 Windows에다가 추가했다.

이러면 사용자 모드의 포인터도 2GB가 넘는 영역에 접근할 수 있으며 최상위 비트가 1이 될 수 있다. 그런데 포인터의 최상위 비트를 자기 멋대로 사용하고 있는 프로그램은.. 뭐 메모리 뻑나고 죽을 수밖에 없다.
64비트 환경에서는 겨우 1비트가 아니라 상위 word 전체를 다른 용도로 전용해도 당장 이상이 없으며 이 추세가 앞으로 몇 년은 가지 싶다. 컴퓨터의 램이 256~512GB나 1테라까지 간다면 모를까..

요즘 컴퓨터야 메모리가 워낙 많고 풍족하니, 굳이 저런 꼼수를 동원하는 프로그램은 별로 없을 것이다.
하지만 저 때가 되면 또 꼼수 부리는 말썽꾸러기 프로그램과의 호환성 때문에 주소 공간을 옛날처럼 상위 16~32GB까지로 봉인하는 옵션 같은 게 또 등장할지도 모른다.;;; HIGH_DPI_AWARE처럼 LARGE_ADDRESS_AWARE 시즌 2 말이다.

여담이지만 Windows의 경우, 실행 파일은 시작 주소가 언제나 64KB의 배수 단위로 부여되기 때문에 HINSTANCE/HMODULE은 아래쪽은 무려 word 덩어리가 언제나 0이 된다. 이 특성을 이용해서 운영체제의 LoadLibraryEx 함수도 하위 몇 비트를 자기 마음대로 활용하기도 한다.

※ 나머지 메모

(1) unsigned 타입에 대해서 단항 연산자 -를 적용해서 -a 이런 값을 구하는 코드를 우연히 보고는 개인적으로 신박하다는 생각이 들었다. 흐음~ Visual C++의 경우 이건 원래 경고인데, 요즘 버전에서는 더 엄격하게 에러로 처리하는가 보다.
-a는 2의 보수의 특성상 ~a+1과(비트 not보다 1 크게) 완전히 동일한 효과를 내며, 앞에 0을 붙여서 이항 연산자로 만들어도 에러를 회피할 수 있다.

(2) ANSI C에서는 함수의 prototype을 선언할 때 매개변수 리스트에 타입만 써 넣고 이름을 빼먹으면 안 된다는 걸 최근에야 알게 됐다.
아니 도대체 왜..? 거기서 매개변수의 이름은 거의 잉여 옵션에 불과할 텐데.. void func(int);라고만 쓰면 틀리고 void func(int x);라고 아무 이름이라도 붙여야 된다는 것이다.
이건 먼 옛날에 C언어에서 void func(a) int a; 같은 구닥다리 문법이 쓰이던 시절의 잔재인 것 갈다.

Posted by 사무엘

2021/05/15 08:35 2021/05/15 08:35
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1887

컴퓨터그래픽에서 벡터 그래픽의 반의어로 픽셀과 비트맵을 다루는 체계를 래스터 그래픽이라고 흔히 부른다. 종이가 아니라 해상도가 상대적으로 낮은 모니터 화면이 주 무대이고, 면을 채우는 기본 단위가 scan line(주사선)이라는 관점에서 정립된 용어이다.

그리고 2D 비트맵(더 정확한 명칭은 래스터..?) 그래픽 API를 보면 어떤 플랫폼용 어떤 언어의 라이브러리이든지 점과 직선, 곡선을 그리는 함수가 있고, 사각형과 원을 그리는 함수가 있다. 이게 기본이다.
점이나 사각형이야 그리는 방식이 너무 trivial하니 제끼고, 원이나 곡선을 빠르게 그리는 원리는 기하 알고리즘의 일종으로 다뤄지기도 한다. 그 단순한 직선조차도 굵기가 2픽셀 이상이 되면 중심점을 생각해야 할 것이고, 무거운 부동소수점 연산 없이 anti-aliasing까지 하면서 그린다는 조건이 추가되면 결코 쉽지 않은 일이 된다.

그리기 기능 중에서 특정 픽셀부터 시작하는 flood fill은 무척 독특한 동작이다. 기하 알고리즘이라기보다는 스택 메모리를 동원해서 컴에게 길 찾기 재귀호출 노가다를 시키는 코딩의 영역이다. 빼곡한 미로의 내부에 있는 한 점에서 flood fill을 시켜 보면 이건 본질적으로 길 찾기와 다를 바 없다는 걸 알 수 있을 것이다.

글쎄, flood fill은 그래픽 에디터에서 사용자가 내리는 채우기 명령을 구현하는 형태로나 쓰이지, 직선과 곡선, 사각형과 원처럼 그림을 그리는 구성요소로서 프로그램이 내부적으로 사용할 일은.. 정말 아주 특수한 상황이 아니라면 없을 것이다. 도형 자체를 처음부터 내부가 채워진 형태로 그려야지, 도형의 윤곽만 그린 뒤에 도형 내부의 임의의 점을 따로 주고 채우는 건 몹시 비효율적이기 때문이다.

그래서 그래픽 라이브러리에는 다각형을 그리는 함수가 있다. 다각형의 경계선만 찍찍 그리는 것이야 LineTo만으로 얼마든지 할 수 있으므로, 이런 함수는 내부가 채워진 다각형을 그리는 것이 핵심이다. 그러니 이 함수는 다른 함수와 달리, 반드시 다각형의 꼭지점들이 담긴 배열을 전달받아야 한다.
옛날 도스 시절의 베이식은 타 언어들에 비해 그래픽 모드의 접근성이 좋았지만, 정작 다각형을 그리는 API는 없었다.

그럼 다각형을 채우는 기능은 어떤 방식으로 동작하는 걸까?
이걸 구현하기 위해서는 어떤 점이 다각형의 내부에 속하는지를 판단해야 한다. 더 나아가서 이 점에서 한쪽으로 scan line을 그어 나갈 때 어디까지가 동일하게 다각형의 내부 또는 외부인지를 판단해야 한다.

이걸 판단하는 방법은 의외로 간단하다. 그 점으로부터 아무 방향으로(예: x축 양의 방향) 한없이 직선을 그을 때, 그 선이 다각형을 구성하는 선분과 얼마나 몇 번이나 마주치는지를 판단하면 되며, 이걸 판단하는 방법도 크게 두 갈래로 나뉜다. 바로 (1) 홀짝 아니면 (2) 0여부이다.

홀짝법은 마주친 선분이 짝수 개이면 다각형의 외부이고, 홀수 개이면 내부라고 판단한다. 다시 말하지만 이 가상의 선은 정말 아무 방향으로나 그리면 된다. 다각형이 모든 방향으로 닫혀서 내부에 공간이 존재한다는 사실 자체가 이 판별법의 correctness를 보장해 준다.

0여부는.. 홀짝보다 더 절묘하다. 초기값이 0인 가중치라는 걸 두는데, 마주친 선분이 우리가 그은 가상의 선을 위에서 아래로 교차한다면 가중치에 1을 더한다. 그렇지 않고 아래에서 위로 교차한다면 1을 뺀다.
이렇게 해서 최종적으로 가중치가 양수든 음수든 0이 아닌 값이 나온 점은 다각형의 내부라고 간주하고, 0인 점은 외부라고 간주한다.

0이나 홀짝이나 그 말이 그 말 같은데.. 실제로 자기네 선분끼리 배배 꼬아서 교차하지 않는 일반적인, 평범한 오목/볼록다각형이라면 어느 판별법을 사용하든 결과에는 아무 차이가 없다.
하지만 당장 오각형 별표를 한붓그리기로 그린 궤적을 줘 보면 둘은 서로 차이를 보인다.

사용자 삽입 이미지
Windows API에서는 SetPolyFillMode라는 함수가 있어서 두 방식을 모두 사용해 볼 수 있다. 더 단순한 홀짝법이 ALTERNATE이고 기본값이다. 0여부는 WINDING... Windows 1.x 시절부터 존재해 온 오래된 고전 API여서 그런지, 매크로 상수의 앞에 접두사가 붙어 있지도 않다(PFM_* 같은?? ㅎㅎ).

오각형 별표에서 별의 중앙에 생긴 공간을 보면.. 그 옆으로 다각형 경계를 나타내는 선이 어느 방향이든 두 개가 존재한다(짝수). 그런데 이들은 방향이 둘 다 오르막 아니면 둘 다 내리막이며, 이 때문에 winding value는 nonzero가 된다. 그러니 ALTERNATE일 때는 이 공간이 비워지지만 WINDING일 때는 공간이 채워지는 것이다.

그 위의 더 복잡한 꼬인 사각형도 상황이 비슷하다. 잘 살펴보면 이 궤적도 홀수점이란 게 전혀 존재하지 않으며 한붓그리기가 가능하다.
그런데 WINDING일 때는 궤적이 꼬여서 생긴 내부의 사각형 공간 둘 중에서 좌측 하단 한 곳만 채워져 있다. 그 이유는 역시 저기서만 winding value가 nonzero이기 때문이다.

일반적으로 WINDING(0여부)이 판정하는 다각형 영역은 ALTERNATE(홀짝)의 상위 호환이다. ALTERNATE가 판정하는 영역을 100% 포함하면서 일부 영역을 추가적으로 더 판정한다는 뜻이다. 그렇다고 해서 모든 닫힌 영역을 한 치의 예외 없이 몽땅 내부라고 판정하는 건 아니다.

뭐.. 현실의 벡터 그래픽에서 이 따위 선끼리 교차하는 배배 꼬인 폴리곤을 생성하는 것은 애초부터 권장되지 않는 금지 사항이다. 가령, 속이 빈 오각별을 그리고 싶으면 저렇게 보이는 대로 삼각형 다섯 개로 풀어서 표현하라는 것이다. 윤곽선 폰트 등 벡터 그래픽 편집기들은 그렇게 폴리곤의 모양을 자동으로 수정해 주는 기능도 제공한다.
그러니 이렇게 fill mode의 차이점을 미주알고주알 관찰할 일이 현업에서는 거의 없을 것이고, 이런 건 그냥 학교에서 컴퓨터그래픽스 기초를 공부할 때 이런 방식도 있다는 걸 알기만 하고 넘어가면 될 것 같다.

하지만 그게 전부가 아니다. 다각형 채우기의 기능이 더 확장되면 다음 영역에도 도달하는데, 이때 fill mode의 차이점이 다시 드러나게 된다.

1. 여러 다각형을 한꺼번에 그리기
이건 내부에 구멍이 뚫린 다각형을 그릴 수 있다는 것에 의의가 있다. 구멍은 Polygon 함수를 연달아 호출하는 것으로는 표현할 수 없기 때문이다.

Windows에는 여러 다각형을 한꺼번에 그리는 PolyPolygon이라는 함수가 있다. 그런데 아까처럼 한 다각형에서 변들이 서로 교차하고 꼬였을 때뿐만 아니라, 변은 꼬이지 않았고 여러 다각형들의 영역이 서로 겹칠 때에도 fill mode의 차이는 유의미한 동작의 차이를 만들어 낸다.

사용자 삽입 이미지

위의 그림은.. 뭐 이론적으로는 한붓그리기가 가능하기 때문에 역시 꼬인 단일 다각형으로 궤적을 나타낼 수 있다. 하지만 앞서 예를 들었던 오각별이나 그 사각형 그림과 달리, 일부 점과 점이 겹치는 건 피할 수 없을 것이다. 무슨 말인가 하면, 저 궤적을 꼭지점 좌표의 배열로 기술했을 때, 4개의 선분과 만나는 점은 두 번 등장하는 부분이 생긴다는 것이다.

꼬인 단일 다각형이 아니라 영역이 일부 겹치는 사각형과 삼각형을 서로 떼어서 PolyPolygon으로 그린 경우.. ALTERNATE(홀짝)에서는 짝수 개의 다각형에 속하는 영역은 비우고, 홀수 개에 속하는 영역만 칠한다. 그러고 보니 동작이 뭔가 XOR스러워 보인다. 각 다각형들의 꼭지점이 기술된 방향은 어느 쪽이건 무관하다 (시계 or 반시계 방향)

그러나 WINDING(0여부)일 때는 그 특성상 방향이 같은 다각형들은 겹치더라도 영역을 모두 칠한다. 겉의 껍데기가 시계 방향이라면.. 그 안의 구멍은 반시계 방향으로.. 다른 방향으로 칠해져야 구멍이 비게 된다! 다시 말하자면, WINDING에서도 위의 그림의 왼쪽처럼 중앙이 비어진 그림을 그리고 싶다면 사각형과 삼각형의 좌표 방향이 서로 반대여야 한다.
꼬인 단일 다각형에서 fill mode의 차이점을 설명하는 프로그래밍 서적들이.. 다중 다각형까지 연계해서 동일 개념을 설명하는 경우는 내가 딱히 못 본 것 같다.

2. 직선뿐만 아니라 베지어 곡선까지 포함된 궤적의 내부를 채우기
위와 같은 구멍 감지에다가 곡선 지원까지 포함되면.. 이건 뭐 윤곽선 글꼴 래스터라이저가 번듯하게 완성된다. 물론 본격적인 폰트 엔진은 거기에다 작은 크기에 대비한 정교한 안티앨리어싱과 힌팅, 글꼴 글립 캐시, 더 나아가 복잡한 유니코드 문자 형태 분석까지 추가되는데 이것들 하나하나가 별개의 전문 영역일 정도이다.

FreeType 라이브러리는 그 중에서 제일 저수준인 그리기, 안티앨리어싱, 힌팅까지만 담당한다. 요즘 소프트웨어들은 글자 하나를 찍는 것도 겨우 8*16, 16*16 비트맵 글꼴 찍던 시절과는 차원이 다르게 더 복잡해져 있는 셈이다.
그건 그렇고.. Windows API에는 직선과 곡선이 포함된 도형을 한꺼번에 그리는 것은 윤곽선만으로 한정이다. PolyDraw라는 함수가 있다.

내부를 채우는 것은 한 함수로 지원되지 않으며, path라는 걸 써야 한다. 얘는 Windows GDI가 제공하는 강력한 벡터 그래픽 라이브러리로, 직선, 베지어 곡선, 원과 원호, 심지어 다른 트루타입 글꼴의 글립까지 몽땅 궤적으로 표현해서 한꺼번에 내부를 채울 수 있다. 구멍 처리도 물론 된다.
BeginPath (그리기) CloseFigure (그리기) EndPath 이런 식으로 말이다. 위의 1과 2를 모두 할 수 있다.

내 경험상 트루타입 폰트는 WINDING 방식으로 래스터라이징을 한다. 글꼴 글립을 그릴 때부터 제일 밖의 path는 시계 방향이고, 그 안의 구멍 윤곽을 기술하는 path는 반시계 방향이고, 구멍 안의 칠하는 영역은 또 시계 방향.. 이런 식으로 디자인을 해야 한다.

허나, 예전에 MS Office 2003 이하 버전에서 제공되던 클래식 WordArt는 이 원칙을 지키지 않고 트루타입 글꼴도 홀짝 ALTERNATE 방식으로.. 짝수 회 overlap 영역은 무조건 비웠던 것 같다.
그래서 composite glyph 형태로 표현되는 비완성형 한글 글꼴에서 글립이 겹칠 수 있는 복잡한 글자를 찍어 보면 저렇게 흰 부위 glitch가 발생하곤 했다. (아래 그림에서 ㅆ, ㅠ, ㅔ 부분 참고)

사용자 삽입 이미지

Office 2007 이상부터 제공되는 WordArt는 이 문제가 해결됐다. 그리고 아래아한글의 글맵시도 0여부 WINDING 방식으로 맞게 색칠을 하기 때문에 glitch가 발생하지 않는다.

그러고 보니.. MS Office는 지난 2007때부터 그래픽 엔진이 크게 바뀌었다. 워드아트의 글자 장식 기능도 리뉴얼 됐고 PowerPoint 같은 데서도 직통으로 사용 가능해졌는데, 정작 본가인 Word에서는 2003 이하의 클래식 워드아트가 제공됐다. 다음 버전인 Office 2010부터 Word에서도 동일하게 리뉴얼된 워드아트가 제공되기 시작했다.

Posted by 사무엘

2021/05/12 08:35 2021/05/12 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1885

« Previous : 1 : ... 43 : 44 : 45 : 46 : 47 : 48 : 49 : 50 : 51 : ... 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:
3045931
Today:
1151
Yesterday:
1972