« Previous : 1 : 2 : 3 : 4 : 5 : Next »

들어가는 말

  • 프로젝트 단위: 말 그대로 한 개의 결과물을 생성하는 것을 목표로 하는 한 비주얼 C++ 프로젝트당 하나씩만 생성되는 파일이다. 리소스는 특수한 경우가 아니면 보통 프로젝트마다 하나만 있기 때문에, per-프로젝트인 것으로 간주된다.
  • configuration 단위: 한 프로젝트 내에서 debug나 release 별로 따로 생성되고, x86이나 x64 같은 플랫폼별로 다 따로 생성되는 파일이다.
  • 소스 단위: 번역 단위(translation unit)별로 다 제각각 생성되는 파일이다. configuration에도 물론 종속적이며, 다 따로 생성된다.

※ 프로젝트를 열면 생성되는 것

APS (프로젝트 단위)

전통적인 윈도우용 실행 파일(EXE/DLL)을 빌드하기 위해서는 잘 알다시피 컴파일된 코드뿐만 아니라 리소스도 같이 들어가는데, 그 리소스를 명시해 주는 '리소스의 소스', 일명 리소스 스크립트는 바로 *.rc 파일이다. 그리고 *.rc와 일반 소스 코드 *.cpp는 resource.h에 정의된 심벌들을 통해 동일 리소스를 식별하게 된다.

그런데 매번 일반 텍스트 형태로 된 rc 파일을 resource.h와 엮어서 파싱하자니 불편하다. 리소스 스크립트는 텍스트 에디터를 써서 사람이 손으로 편집한 뒤 컴파일하기에는 적합하지만, IDE 같은 소프트웨어가 자동으로 다뤄 주기에는 비효율적인 구조인 것이다.

그래서 비주얼 C++은 리소스 ID까지 포함하여 리소스 스크립트의 바이너리 representation을 따로 만들어 두고 지낸다. APS 파일이 존재하고 이게 RC나 H 같은 텍스트 소스에 비해 outdate되지 않았다면, 프로그램은 매번 텍스트를 파싱하는 게 아니라 APS 파일을 곧장 읽는다.

비주얼 C++에서 프로젝트를 처음으로 열어서 리소스 뷰로 리소스들을 처음 열람하면, 프로그램이 리소스 컴파일러를 가동해서 뭘 파싱하면서 시간이 오래 걸린다. 하지만 다음에 열 때부터는 리소스가 곧바로 빨리 열리는데, 이것이 바로 APS 파일 덕분이다.

CLW (프로젝트 단위) deprecated

이것은 비주얼 C++ 4~6 사이에, 그 이름도 유명한 MFC Class Wizard (클래스 마법사) 때문에 도입되었던 부가정보 파일이다.
MFC 클래스에서 파생된 윈도우 클래스 같은 데서 메시지 핸들러(마법사의 용도가 굳이 메시지 핸들러뿐인 건 아니지만)를 추가하려면 일단 헤더 파일에 afx_msg void OnXXXX가 추가되어야 하고, 메시지 맵 BEGIN_MESSAGE_MAP() 밑에 ON_MESSAGE_***가 추가되어야 하고, 끝으로 소스 파일에 해당 멤버 함수의 몸체가 추가되어야 한다.

그런데 이 일을 모든 소스 코드를 일일이 파싱하면서 추가 지점을 찾아서 하기란 여간 어려운 일이 아닐 수 없다.
C++은 선언 따로, 정의 따로이고(C#, 자바는 그렇지 않다) 정의부가 반드시 어느 번역 단위에 존재해야 한다는 제약이 전혀 없다. FM대로 하는 건 15년 전의 펜티엄 컴으로는 무리였다.

그래서 편의상 클래스의 선언부와 메시지 맵의 주변엔 클래스 마법사만이 식별하는 문자열이 들어간 주석이 있고, 클래스 마법사는 그 구간을 대상으로만 작업을 신속하게 했다. 그리고 그걸로도 부족해서 클래스 마법사의 파싱 결과가 CLW 파일에 들어갔다. 식별자 주석을 건드리면 클래스 마법사가 제대로 동작하지 못했다.

21세기에 나온 비주얼 C++ .NET과 그 이후 버전은 CLW 파일을 만들거나 사용하지 않으며, 클래스 마법사 주석 없이도 멤버 함수나 핸들러의 추가를 그럭저럭 정확하게 해낸다. 사실 클래스 마법사 자체가 비주얼 C++ 200x에서는 사라졌다가 2010에서부터 부활했다.

※ 빌드하면 생성되는 것

OBJ (소스 파일 단위)

비주얼뿐만이 아니라 전세계의 어느 C/C++ 컴파일러를 돌리더라도, 소스 코드를 컴파일하면 이것이 매 소스, 즉 번역 단위별로 생성된다. 소스 코드를 번역한 기계어 코드가 obj 파일 포맷에 맞게 들어있는데, 때로는 기계어 코드뿐만 아니라 각종 디버깅 정보와 링크 때 링커가 참고할 만한 메타데이터도 잔뜩 가미된다.

static library라고 불리는 LIB는 별개의 포맷이 아니라, 그냥 여러 번역 단위들을 컴파일한 obj들의 컬렉션일 뿐이다. obj를 단순히 lib로 합치기만 할 때는 링크 에러가 나지 않는다(즉, 선언된 심벌들이 반드시 정의되어야 할 필요가 없다.)

RES (configuration 단위)

리소스 스크립트를 컴파일하여 생성되는 결과물이다. 리소스 스크립트의 바이너리 최적화 형태인 APS와 무엇이 다르냐고 물으신다면, 차이가 적지 않다.
APS는 리소스 스크립트 파일의 표현 형태만 메모리 친화적으로 바꾼 것이기 때문에 ID_RADIO1 같은 상수 명칭의 문자열 원형과 심지어 조건부 컴파일을 위한 스펙까지 다 보존되어 있으며, 참조하는 비트맵 같은 데이터 파일도 파일명 형태로 존재한다. APS 파일로부터 RC 파일과 resource.h 파일을 복원해 낼 수 있다.

그러나 RES는 상수는 다 숫자로 박히고 참조하는 데이터 파일도 모두 내부에 embed되었으며, 이 상태 그대로 실행 파일에다 링크되어 들어가기만 하면 되는 상태인 것이다.

PCH (configuration 단위)

pre-compiled header인 stdafx.h와, 이에 대응하는 번역 단위인 stdafx.cpp를 컴파일하여 얻은 각종 컴파일 context들, 즉 함수와 클래스 선언, #define 명칭 등등을 바이너리 형태로 보관하고 있는 파일들이다. 이게 있으면 stdafx.h를 인클루드하라는 명령은 실제 헤더 파일을 파싱하는 게 아니라 그냥 pch 파일을 참조하는 것으로 대체된다.

컴파일러의 버전이 올라가고 각종 플랫폼 SDK의 크기가 커질수록 이 파일의 크기도 야금야금 커져 왔다. 이거 없이는 C++은 살인적인 인클루드질 때문에, 느린 빌드 속도를 도저히 감당할 수 없다.

PDB (configuration 단위)

빌드 결과 만들어진 EXE/DLL에서 기계어 코드의 어느 부분이 어느 소스의 몇째 줄에 대응하는지(소스 코드 자체는 없고 소스의 경로만), 이 함수에서 이 지역변수의 이름이 무엇인지 등을 담고 있는 디버그 정보 데이터베이스이다.

디버그 모드가 아니라 릴리스 모드로 빌드한 최적화된 실행 파일이라도, PDB 파일을 참조하게 하는 최소한의 정보만이라도 남겨 두면, 나중에 프로그램이 뻗는다거나 할 때 소스상으로 최소한 어느 지점에서 뻗었는지를 개발자의 컴에서 확인해 볼 수 있다. 개발자의 컴엔 직전에 이 바이너리를 빌드하면서 같이 생성된 PDB 파일이 존재하기 때문이다.

ILK (configuration 단위. 대개 디버그 빌드에서만)

증분 링크(incremental link)를 위한 context 정보가 들어있다.
이것은 프로그램의 빌드 속도를 올리기 위한 테크닉이다. 매번 링크를 처음부터 일일이 새로 하는 게 아니라, 처음에 빌드할 때 바이너리를 좀 여분을 둬서 듬성듬성 큼직하게 만들어 두고, 다음부터는 바뀐 obj 파일 내용만 기존 바이너리의 자기 지점에다 대체하는 방식으로 빌드를 신속하게 끝낸다. 혹은 뒷부분에다가 새로운 빌드 내용을 계속 추가해 넣기만 하고, 예전 빌드 내용을 무효화시키는 방법도 쓴다.

요즘 디버그 빌드가 단순히 최적화를 안 한 것 이상으로 릴리스 빌드보다 빌드된 바이너리의 크기가 유난히 큰 이유가 여기에 있다. 게다가 Edit and continue 기능을 위해서도 여분 공간이 필요하기 때문에 크기가 커질 수밖에 없다. 디버그 빌드 바이너리를 바이너리 에디터로 들여다보면, 온통 0xCC (no op)으로 도배가 되고 내부가 헐렁함을 알 수 있다.

MS 오피스도 2007 이전 버전을 보면 방대한 워드/엑셀 문서를 편집할 때 바뀐 내용만 짤막하게 저장하는 옵션이 있었다. 그게 일종의 증분 저장 기능이다. 지금은 그게 보안상으로 문제가 되기도 하고 문서 파일 포맷이 크게 바뀌었으며, 굳이 증분 저장을 안 써도 될 정도로 PC 성능이 좋아졌다고 여겨져서 그런 기능이 없어졌지만 말이다.
증분 링크는 보통은 디버그 모드 빌드에서만 쓰인다.

VC???.idb (configuration 단위. 대개 디버그 빌드에서만)

ILK 파일과 마찬가지로 빌드 시간의 단축을 위해 존재하는 파일이다.
디버그 모드로 빌드를 해 보면, 헤더 파일이 바뀌었더라도 해당 헤더를 인클루드하는 cpp 파일들이 전부 리빌드되는 게 아니라 가끔 'Skipping.. (no relevant changes detected)'이러면서 넘어가는 파일도 있다. 그리고 대체로 이런 컴파일러의 판단이 맞다. 헤더 파일을 고쳤더라도 클래스의 선언부 같은 크리티컬한 부분이 아니라 그냥 주석 같은 trivial한 부분만 바뀌었기 때문에 굳이 리빌드가 필요하지 않다는 걸 어떻게 판단할까?

컴파일러가 제공하는 Enable Minimal Rebuild (/Gm) 옵션 때문에 가능하다. 이게 지정되면 빌드 과정에서 프로젝트명이 아니라 고정된 이름의 의존성 판단용 부가정보 파일이 생긴다. ???는 해당 비주얼 C++의 버전이다. 2008의 경우 90, 2010의 경우 100.

정리하자면, 빌드와 함께 생성되는 파일들 중, 실제로 링커에 의해 EXE/DLL 따위를 만드는 데 동원되는 파일은 OBJ, RES이다.
빌드 시간을 단축시키는 데 쓰이는 파일은 PCH, IDB, ILK이다.
PDB는 프로그램의 문제 추적을 위해 추후에 쓰이는 파일이다.

※ 편의 기능 + 빌드

SBR (소스 파일 단위), BSC (configuration 단위)

자, 이 파일은 빌드를 하면 생성되지만, 프로그램의 빌드나 디버깅을 위해서 반드시 생성해야만 하는 파일은 아니다.
방대한 양의 소스 코드를 컴파일하고 나면 컴파일러는 그 소스 코드의 모든 내부 구조에 대해서 알게 된다. 그걸 알아야만 기계어 코드를 생성할 수 있을 테니까.

컴파일이 끝났다고 그 정보를 그냥 버리는 건 아깝기 때문에, 일정한 파일 포맷을 제정하여 이것을 소스 코드에 대한 browsing에 활용할 수 있다. 가령, 이 클래스 멤버 함수의 정의는 어디에 있고, 이 함수가 호출하는 함수와, 이 함수를 호출하는 함수와의 그래프 관계는 어떻고 하는 것 말이다. 소스 코드가 텍스트라면, browse 정보는 정교하게 짜여진 색인인 셈이다.

이 개념과 파일 포맷은 비주얼 C++의 아주 초창기 시절부터 존재했다.
그리고 비주얼 C++은 버전 6까지는, 프로젝트를 빌드할 때 browse 정보도 같이 이렇게 덤으로 빌드되게 해서 browse 정보를 조회하는 기능을 갖추고 있었다. SBR과 BSC의 관계는 C/C++ 소스 코드에서 OBJ와 EXE의 관계와 정확히 같다. 한 번역 단위를 컴파일하면 한 SBR이 생겼고, SBR들을 뭉쳐서 BSC 파일이 생성되었다.

물론 이렇게 하면 빌드 시간이 더욱 길어졌고, 굳이 browse 기능을 쓰지 않는 사람도 있었기 때문에 이 기능은 철저히 선택사항이었다. 그리고 닷넷부터는 이 정보를 만들지 않더라도, 뒤에서 설명할 인텔리센스 정보만으로 IDE 차원에서 browse 대체 기능을 갖추기 시작했다.

※ 인텔리센스

NCB (프로젝트 단위) deprecated

sbr/bsc보다는 나중에, 시기적으로는 clw와 비슷한 타이밍(비주얼 C++ 4)에 만들어진 파일 포맷이다.
바야흐로 비주얼 C++ 4에서는 최초로 Class View라는 게 생겨서 프로젝트에 존재하는 모든 클래스와 멤버, 전역 변수/함수들을 표시하는 기능이 추가되었다. ncb는 browse 정보를 만드는 것만치 소스를 심도 있게 일일이 다 까 보지는 않고, 그보다는 단순하게 코드를 파싱하여 해당 기능을 빠르게 구현하는 데 필요한 부가 정보를 저장했다.

Class View가 도입되었던 초창기에는 소스 코드를 매번 빌드는 아니어도 저장을 해야만 컨텐츠가 업데이트되었다. 그나마 저장하지 않고도 실시간으로 업데이트가 되기 시작한 건 VC 6부터이다.
그리고 VC 6에서는 잘 알다시피 초보적인 수준의 인텔리센스 및 멤버 표시/자동 완성 기능이 구현되었고, 그 정보 역시 ncb 파일에다 저장되었다. 당연히 같은 프로젝트를 만들어도 ncb 파일의 크기는 더욱 커지게 됐다.

비주얼 C++이 버전업되면서 인텔리센스는 성능이 더욱 강력해졌다. 바로 닷넷에서부터는 #define 심벌이 추가로 인텔리센스의 혜택을 입기 시작했으며 템플릿도 제대로 지원되기 시작했다. 오동작 빈도도 더욱 줄었다.

그러나 이 모든 것은 여전히 10년 전의 ncb 파일을 기반으로, 진품이 아닌 가짜 parser를 임기응변 식으로 확장하면서 구현된 것이기 때문에, 어느 수준 이상의 정확도를 낼 수는 없었으며 복잡한 C++ 문법의 모든 것을 수용하는 데에도 근본적인 한계가 있었다.

가령, 클래스 멤버 함수의 선언이 복잡한 #define 매크로 안에 숨어 있으면 Class View에 이것이 제대로 나타나지 않았다. 갑자기 빌드 configuration이나 플랫폼을 확 바꿔 버리면 인텔리센스가 멘붕을 일으켰으며, 복잡한 조건부 컴파일 구간에 숨어 있는 코드도 인텔리센스가 상황 파악을 제대로 못 하는 경우가 많았다. 멘붕의 정도가 심하면 인텔리센스가 아예 동작을 멎어 버리기도 했기 때문에, 수시로 ncb 파일을 지우고 다시 만들어 주는 건 필수 작업이었다.

SDF (프로젝트 단위), IPCH (configuration 단위)

위와 같은 기존 ncb 기반 인텔리센스의 문제를 극복하고자 비주얼 C++ 2010은 안 그래도 C++11 때문에 문법도 대폭 확장해야 하는데 이 기회에 인텔리센스 엔진을 완전히 갈아 엎었다. SQL server compact edition이라는 전문 DB 엔진을 쓰기 시작했다.

2010부터는 가짜 parser가 아니라 진짜 컴파일러와 똑같은 수준의 parser가 background에서 모든 소스와 헤더 파일들을 일일이 파싱하여 실시간으로 심벌 정보를 고친다. 정확한 문맥을 파악하고 있기 때문에 100% 정확한 인텔리센스가 제공되며, 예전처럼 좀 오동작한다 싶어도 잠시 기다려서 파싱 정보가 갱신되고 나면 곧장 똑바로 동작하기 시작한다.

다만, 이런 첨단 기술이 공짜로 된 건 아니기 때문에, 어지간한 C++ 프로젝트는 이제 인텔리센스 파일만 수십~100수십 MB씩 디스크를 쳐묵쳐묵 하는 대가를 감수해야 한다. 어느 프로젝트를 열든지 동일하게 공유되는 MFC나 플랫폼 SDK의 인텔리센스 정보는 여러 프로젝트들이 한데 공유만 할 수 있어도 인텔리센스의 용량이 크게 줄어들 텐데, 무척 아쉽다.

그래도 비주얼 C++ 제작진에서 일말의 배려를 했다 싶은 대목은, 인텔리센스 DB 파일이 생성되는 곳만 한 곳에 따로 대체 지정이 가능하다는 것이다. 프로젝트-옵션이 아니라 도구-옵션에서 “텍스트 편집기-C/C++/고급”으로 가면 fallback location을 지정하는 옵션이 있으며, 이것만 해 주면 비주얼 C++로 만드는 모든 프로젝트들의 인텔리센스 DB는 거기 아래로 한데 모이게 된다.

이렇듯, 비주얼 C++ IDE나 컴파일러가 생성하는 보조 파일들의 용도와 배경에 대해서 공부하면 C/C++ 언어의 특성을 알 수 있고, 프로그래밍 언어에 대한 비판적인 안목, 그리고 언어의 비효율을 극복하고 조금이라도 개발 도구의 생산성을 올리기 위해 해당 제작진이 어떤 꼼수를 동원했는지에 대해서도 알 수 있다.

Posted by 사무엘

2012/10/16 08:30 2012/10/16 08:30
,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/744

1. 심벌 검색 기능의 퇴화(?)

예전에도 글에서 언급한 적이 있지만, 비주얼 C++에는 Alt+F12를 누르면 심벌 검색을 할 수 있다. 주어진 프로젝트의 소스 코드에 등장하는 모든 명칭들(클래스, 함수, 전역 변수 등등)의 선언과 정의가 있는 곳을 곧바로 찾아갈 수 있으니 이건 매우 편리한 기능이 아닐 수 없다.

이 기능이 특히 강력한 이유는 내가 해당 프로젝트의 내부에서 선언한 명칭뿐만 아니라, 인클루드 파일에 있는 명칭들도 전부 조회할 수 있기 때문이다. 따라서 C/C++ 라이브러리에 있는 함수나 윈도우 플랫폼 SDK 내지 MFC 라이브러리에 있는 방대한 명칭들도 다 조회가 되어서 해당 명칭의 출처를 쉽게 알아낼 수 있다.

어차피 소스 코드를 빌드하여 precompiled header나 인텔리센스 정보를 만들 때 이런 정보들을 다 한 번씩 파싱을 하기 때문에, 심벌 검색은 최적화된 자체 데이터베이스를 대상으로 신속하게 행해진다. 무식하게 수백, 수천 개의 헤더와 소스 파일들을 텍스트 형태로 찾는 find in files 형태가 아니다.

그런데, 비주얼 C++ 2010을 보니 심벌 검색은 해당 프로젝트에서 직접 선언한 명칭만 가능하고, 그 프로젝트가 stdafx.h에다가 인클루드하여 사용하는 플랫폼 SDK, MFC 같은 것들의 명칭은 조회되지 않는다.
200x 시절과 동일하게 '참조에서 찾기' 옵션을 켜고, 검색 범위를 'All components'로 바뀌었는데도 여전하다. 이 기능에 무슨 문제가 생겼는지 궁금하다.

사용자 삽입 이미지사용자 삽입 이미지

(WM_CREATE 위치가 뜨는 2003 좌, 하지만 뜨지 않는 2010 우)

물론, 소스 코드에서 MFC나 플랫폼 SDK의 명칭을 참조하는 부분에서 F12를 눌러 보면 여전히 해당 명칭의 선언부로 가긴 간다. 하지만 명칭을 직접 입력해서 찾는 심벌 검색 기능은 왜 그게 불가능해진 걸까?

보아하니 그저 닷넷 프레임워크 라이브러리의 명칭을 조회하는 기능에만 신경 쓰느라, C++ 네이티브 개발 쪽은 지원이 간과되기라도 한 건지? 2010은 그렇잖아도 인텔리센스에다 빌드 보조 파일들이(*.sdf, *.ipch) 예전에 비하면 기겁을 할 정도로 방대해졌는데 편의 기능은 도리어 없어지면 어떡하냐 말이다.

2. 메뉴 편집기의 우클릭

C++ 프로젝트를 새로 만들거나 열어서 리소스에서 메뉴 편집기를 연다. 아, 프로젝트를 만들 필요 없이 그냥 리소스 템플릿만 하나 만들어서 메뉴를 생성해도 되겠다.

열었으면 클라이언트 화면의 빈 공간을 아무 데나 우클릭하여 메뉴 편집기에 대한 컨텍스트 메뉴를 연다. 그 후 마우스로 다른 곳을 클릭하거나, 명령을 선택하거나, ESC를 눌러서 컨텍스트 메뉴를 없앤다.
그러면 컨텍스트 메뉴가 화면 좌측 상단에 한 번 또 나타나서 사용자를 성가시게 할 것이다.

이는 명백한 버그이다. 대화상자 같은 다른 리소스 편집기에서는 우클릭을 해도 이런 현상이 생기지 않는다.
2010뿐만이 아니라 무려 2003에서도 동일한 현상이 발견된다. 거의 10년 묵은 버그라는 뜻인데 아무도 신경을 안 쓰는지 지금까지 고쳐지지 않았다.
설마 6.0에서까지 이랬을 것 같지는 않은데 잘 모르겠다. 아직도 6.0 쓰시는 분이 계시면 확인 요망.

여담이지만 마우스가 아니라 Shift+F10 같은 키보드로 컨텍스트 메뉴를 열면 이런 현상이 생기지 않는다.
그리고 화면 빈 공간이 아니라 편집 중인 메뉴 항목의 경우 우클릭하더라도 역시 그 현상이 생기지 않는다.
이건 아주 사소한 코딩 실수로 보이고, 몇 라인만 고치면 바로 제거할 수 있는 버그이다만, 10년에 가까운 시간 동안 발견하고 지적한 사람이 없었나 보다.

C#이나 VB, C++/CLI 같은 닷넷 환경의 경우, 폼(네이티브 개발 환경으로 치면 대화상자)에다가 메뉴 컴포넌트를 집어넣으면 그 자리에서 바로 메뉴를 편집할 수 있게 되어 있으니 네이티브 개발과는 환경이 꽤 다르다.
닷넷 프로그램도 기본 메뉴는 일반 윈도우 운영체제가 제공하는 표준 네이티브 메뉴 형태로 나오지 않겠나 하고 생각해 왔는데, 놀랍게도 그렇지 않다. 비주얼 스튜디오 200x와 비슷한 형태인 싸제 메뉴이다.

3. 툴바 편집기의 화면 잔상

이뿐만이 아니다.
리소스 중에서 툴바 편집기를 보면, 툴바 아이템들을 순서대로 하나씩 찍어 보기만 해도 예전 selection 흔적이 지저분한 잔상으로 잔뜩 남는다. 저건 절대로 multiple selection을 나타내는  게 아니며, WM_PAINT 메시지만 다시 받아도 잔상은 싹 없어진다.

사용자 삽입 이미지
열기, 저장, 모두 저장, 인쇄 아이콘의 테두리에 생긴 잔상들을 보라.
그리고 믿어지지 않겠지만 이건 비주얼 C++ 2003 시절부터 변함없던 버그이다!
전세계에서 압도적인 인지도와 점유율을 자랑하는 개발툴에 이런 초보적인 버그가 있다는 게 믿어지는가? 6.0은 그렇지 않았던 걸로 난 기억한다.

아이콘의 배치 순서를 조정하거나 중간에 여백을 넣기 위해서 드래그 드롭만 해도 잔상이 잔뜩 쌓인다. 구체적으로 재연 조건과 증상을 일일이 기술하기에는 구차하나, 잔상 현상은 2010에서 조금 더 심해졌다.

4. 속성 대화상자

비주얼 C++ 6.0까지는 전통적으로 가로로 길쭉한 자신만의 context-sensitive한(문맥 민감. 사용자가 키보드 포커스를 두거나 선택한 개체나 문서에 따라서 대화상자 내부 내용이 수시로 동적으로 바뀌는) 속성 대화상자가 있어서 Alt+Enter를 누르면 언제든지 그게 떴었다. old timer라면 추억의 옛날 스타일 대화상자를 기억하실 것이다.

사용자 삽입 이미지
그게 닷넷부터는 비주얼 베이직 스타일의 프로퍼티 그리드로 다 바뀌었다.
특히 프로젝트 설정 대화상자(VC6 표준 단축키 기준 Alt+F7)도 이 형태로 리모델링된 것 여러분들 다 아실 것이다.

그러나 프로퍼티 그리드가 커버하지 못하는 UI가 있었으니 그것은 바로 preview 기능이다.
비트맵, 대화상자, 메뉴 등 리소스들을 일일이 열 필요 없이 찍어 보기만 해도 이놈이 대략 어떻게 생겼는지 간략히 표시해서 보여주는 기능인데,
이건 2차원적인 공간에다 뭔가를 그려야 하기 때문에 기존 프로퍼티 그리드로 커버할 수가 없다.

그래서 별도의 버튼을 누르면 결국 과거 6.0 시절의 속성 대화상자와 비스무리하게 생긴 대화상자가 떠서 미리보기를 보여주는 기능이 들어갔다. 뭐, 여기까지는 뭐 나쁘지 않다. 메뉴나 대화상자가 좀 더 깔끔하게 그려졌으면 좋겠는데 10년 전이나 지금이나 하나도 바뀐 게 없이 똑같이 엉성하다는 건 아쉽지만 말이다.

그런데 과거의 200x 시절에는 미리보기를 보는 중에도 키보드 포커스는 각종 리소스들을 고르는 화면에서 계속 유지가 되어서 위· 아래 화살표를 누르며 리소스들을 조회할 수 있었는데,
2010부터는 뭔가를 선택하고 나면, 키보드 포커스가 미리보기 대화상자로 바뀌어 버린다. 그래서 마우스로 해당 아이템들을 일일이 찍어야 한다.

역사적으로 비주얼 C++은 4.0 때 Developer Studio (MSDEV)라는 첫 UI가 갖춰진 이래로 닷넷으로 넘어갈 때 대대적인 리모델링을 거쳤고, 2010 때는 WPF 기반으로 또 IDE의 구현체가 크게 바뀌었다.

요즘 다시 C++11 지원처럼 C++ 지원이 강화되고는 있다지만, 기존 코드들이 리팩터링되는 과정에서 예전에는 없던 사소한 버그들이 끼어 들어가는 게, MS에서 닷넷에 비해 네이티브 환경 개발에 점점 소심해지고 있다는 생각이 들어서 아쉽다. 닷넷과 관련된 개발 환경이라면 저런 버그가 들어갔을 리가 없을 텐데 말이다.

다음은 버그까지는 아니고, 비주얼 C++과 관란하여 추가로 떠오르는 생각들이다.

1. 비주얼 C++은 32비트 시절 이래로(무려 4.x부터) 80비트 초정밀 부동소숫점인 long double을 무시하고, 이것도 일반 double과 완전히 동일한 64비트 부동소숫점으로만 제공하는 것으로 잘 알려져 있다.
난 32비트 CPU에서는 10바이트 단위로 정보를 처리하는 게 불편해저서 long double이 도태한 게 아니겠나 정도로만 생각해 왔다.
그런데 나중에 알고 보니 인텔 CPU엔 80비트 부동소숫점을 연산하는 명령 자체는 존재한다고 한다. 단지, MS 컴파일러가 이를 활용하지 않는다고.

이것까지 지원해야 하면 %타입 문자부터 시작해서 언어 라이브러리에도 그야말로 대대적인 칼질이 가해져야 하는 건 사실일 것이다. 그런데 그렇다고 해서 있는 CPU의 기능을 컴파일러가 활용하지 않는 건 좀 문제가 있어 보이는데?
인텔 컴파일러 같은 다른 벤더 제품 중에는 long double을 쓸 수 있는 놈이 있는지 궁금하다.

2. 오늘날 거의 모든 IDE와 에디터들은 탭을 customize할 수 있다.
화면에 표시되는 탭 길이를 조절하고(보통 거의 다 4를 쓰지만), 코딩용 자동 들여쓰기를 할 때 공백을 삽입할지 탭을 삽입할지를 지정할 수 있다. 그리고 언어별로 어떤 탭 설정을 사용할지도 지정 가능하다.

그런데 여기서 한 발 더 나아가서, 읽어들이는 소스 코드의 형태를 보고 탭 컨벤션을 자동 감지하게 할 수는 없나?
space로 맞춰져 있는 소스 코드에다가 눈치 없게 탭으로 들여쓰기를 삽입한다거나 혹은 그 반대로 하는 것. 불편하다.

자동 들여쓰기를 구현했을 정도라면 앞뒤의 중괄호가 어떻게 돼 있고 whitespace들이 space인지 tab인지 주변 context들은 다 파악했다는 뜻이다.
따라서 조금만 더 센스 있게 동작하게 만드는 것은 마치 코드의 줄바꿈 문자의 종류를 자동 감지하는 것만큼이나 그렇게 어려운 일이 아니리라 여겨진다.

Posted by 사무엘

2012/07/29 08:33 2012/07/29 08:33
, ,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/713

비주얼 C++ MFC의 역사 -- 下

현재 윈도우 운영체제의 GUI는 잘 알다시피 윈 2000/ME까지 유지되던 고전 테마, 그리고 XP 테마와 비스타/7 테마가 서로 따로 논다.
MS 오피스도 XP/2003/2007이 따로 놀고,
거기에다가 비주얼 개발툴의 디자인도 2005/2008/2010이 다 달라진다.

어디 그뿐인가. 현재 운영체제의 configuration에 따라 테마가 나타나는 모양도 달라져야 한다. 가령, 오피스 2003은 전반적으로 파란 색상이지만 운영체제가 회색 고전 테마일 때는 은색이 깔림. 그 반면 오피스 2007은 독자적인 배색 컨셉이기 때문에 운영체제의 상태에 관계 없이 여전히 은은한 하늘색 색상이 되는 게 맞다.

이런 세세한 알고리즘은 reverse engineering이라도 해서 알아내야 할 텐데, GUI 툴킷 만드는 일은 정말 장난 아니게 어려울 것 같다. 아래아한글의 스킨을 개발하는 팀도 고생 무지하게 했을 거라는 생각이 든다. 차라리 운영체제 GUI를 완전히 생까던 9x  시절이나, 반대로 잠시 100% 운영체제 표준 GUI만 따르던 워디안 시절이 나았겠다.

자, 이렇게 GUI 비주얼들이 난립하고 기존 MFC는 이런 수요를 충족하지 못한 채 시간만 자꾸 흐르고 있었다. 그러던 차에 MS는 결단을 내렸다. 바로 비주얼 C++ 2008 플러스 팩. MFC42 시절 이래로 MFC에 대대적으로 기능을 추가하여 역대 오피스와 비주얼 툴들의 UI, 그리고 심지어 리본 UI까지 MFC에다 넣어 줬다.

MFC의 새단장 소식이 전해지던 당시, 많은 개발자들은 MS가 자기네 오피스 팀이 개발한 오리지널 GUI 소스를 리팩터링해서 전해 줄지 무척 기대했었다. 하지만 아쉽게도 그건 아니고, 이미 BCG라는 러시아 회사에서 개발하여 판매 중이던 제3자 라이브러리를 MS라는 브랜드만 넣어서 제공하는 형태가 되었다. MS의 GUI는 MFC를 써서 개발된 것도 아니고, 모듈 구조를 보아하니 외부에 선뜻 떼어 줄 만한 상태가 아닌 모양이다.

이 작업의 결과로 MFC DLL은 덩치가 정말 크고 아름다워져서, 1MB 초반이던 게 4MB를 훌쩍 넘어갔다. CWinApp, CFrameWnd는 새로운 GUI 기능과의 연동을 위해, Ex라는 접미사가 붙은 CWinAppEx, 그리고 CFrameWndEx라는 파생 클래스가 추가되었다.

그런데, MS가 제3자 중에서도 왜 하필 BCG 라이브러리를 선택했는지에 대해서 불만을 제기하는 사람이 있다. 김 민장 님이 굉장히 옛날에 쓰신 개념글을 하나 읽어보자.

일단, 한눈에 BCG 제품의 메뉴 폰트가 한 픽셀 작음을 알 수 있다. 메뉴뿐만 아니라 툴바 아이콘도 가로 폭이 1픽셀 작은 것 같고, "Solution Explorer"의 글씨도 작다. (중략) 데모 프로그램 다운 받고 단 3분 동안 들여다 봤는데도 벌써 이상한 점 서너 개가 나왔다. 그러니 BCG 제품을 믿지 못하겠고 사용하기가 꺼려지는 것이다.


특히 메뉴의 글씨의 크기가 작은 것은 비주얼 C++ 2008/2010에서까지 그대로 이어져 오고 있는 걸 본인 역시 확인했다. 이건 꽤 심각한 문제인데? (왼쪽이 good, 오른쪽이 bad)

사용자 삽입 이미지사용자 삽입 이미지
도대체 왜 이렇게 동작하는 걸까? 궁금해서 MFC의 소스를 들여다봤다. 내가 발견한 문제점은 두 가지이다.

afxglobals.cpp를 보면 MFC의 GUI 구성요소들이 한데 공유하는 GDI 오브젝트들이 한데 모여 있으며, 그 중에는 글꼴 오브젝트도 응당 있다. 그런데 여기 생성자를 보면,

m_bUseSystemFont = FALSE;

로만 되어 있고, SystemFont라고 MFC 소스 전체를 검색해 봐도 이 값을 바꾸는 멤버 함수 같은 건 어디에도 나오지 않는다. 메뉴의 글씨체는 운영체제의 시스템 글꼴로 나오는 게 일반인데(한글 윈도우의 고전 테마에서는 그냥 ‘굴림’처럼), 저게 TRUE가 아닌 FALSE인 한은 운영체제 한글 윈도우 고전 테마 + 오피스 구버전 테마 모드에서도 메뉴의 글꼴은 Segoe 내지 Tahoma로 자기의 독자적인 글꼴로 출력된다.

그리고 더 큰 문제는 UpdateFonts 함수에 있다. Adjust font size라는 주석 하에

if (nFontHeight <= 12)
    nFontHeight = 11;

라는 글꼴 보정 코드가 있다. 그런데 이 잘못된 보정 때문에 BCG 툴킷이 정상보다 글씨가 작게 찍힌다. 도대체 이 코드가 왜 들어갔는지 모르겠다. 12픽셀이던 걸 11픽셀로 줄이면, 한글· 한자가 가장 잘 찍히는 9포인트보다 글자 크기가 한 단계 더 작아져 버린다. 아마 영문 오피스 2007의 글꼴이 여타 비주얼에도 획일적으로 적용되는 듯하다.

한눈에 봐도 MS 원본 프로그램과는 UI가 다르게 찍히는 GUI 툴킷을 최소한의 보정도 없이 MS가 자기 이름으로 어떻게 MFC에다 내장시켜서 내놓은 걸까? 물론 이런 시도조차 없는 것보다는 낫지만, 역시 네이티브 C++ 개발자로서 꽤 안타까운 일이다. 차라리 제3자 라이브러리 시절에는 소스를 고쳐서 라이브러리를 새로 빌드할 수라도 있지만, 그 거대한 MFC의 내부에 내장이 되어 버린 코드는 고칠 수도 없는 노릇이고.

김 민장 님의 블로그에 나와 있듯, BCG보다는 Codejock이라는 미국 회사에서 개발한 Extreme Toolkit이라는 GUI 라이브러리가 원본과의 고증(?)이 더 잘 돼 있고 품질이 좋다고 그런다.

이렇듯, MS는 자기네가 처음으로 구현한 기능을(뭐, 오피스 팀이니, VS 팀과는 다른 부서이지만) 외부 회사로부터 구현체를 사 오는 기묘한 방법으로 집어넣어서 MFC를 확장했다. 일단 MS 내부에서 MFC를 자기네 프로그램의 개발에 거의 안 쓴다는 점을 염두에 둘 필요가 있겠다. -_-;; 진짜로 워드패드와 그림판을 빼고는 거의 없다.

본인 역시 일단 중요 제품인 <날개셋> 한글 입력기를 MFC 없이 순수 API + 간단한 싸제 라이브러리만으로 개발하기 시작했으니, MFC와는 직접적으로 결별했다. 하지만 C++과 윈도우 플랫폼이 살아 있는 한, MFC의 중요성과 의의는 그리 금방 격하되지 않을 것이다.

다만, 덩치가 커져도 너무 커져 버린 건 진짜로 아쉬운 점이다. 그렇게 살이 뒤룩뒤룩 찐 네이티브 환경을 쓰느니, 차라리 훨씬 더 생산성 좋은 닷넷이 그 역할을 조금씩 대체하고 있는 게 아닐까 싶다.
그리고 여담이지만, 윈도우, 오피스, VS는 앞으로도 또 비주얼이 완전히 확 바뀌는 일이 있을지 궁금하고 기대-_-되기도 한다. ^^

Posted by 사무엘

2012/03/29 09:10 2012/03/29 09:10
, ,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/661

비주얼 C++ MFC의 역사 -- 上

옛날에 비주얼 C++의 역사에 대해서는 거창한 글을 쓴 적이 있는데 MFC 자체에 대해서는 의외로 블로그 개설 이래로 글을 쓴 적이 없었던 것 같다. 그래서 오늘은 이 주제로 한번 칼럼을 써 보겠다.

MFC는 잘 알다시피 C 언어 기반인 윈도우 API를 C++로 얇게 포장하는 한편으로, C++의 특성을 살려 더욱 생산성 있고 편리한 윈도우 응용 프로그램 개발을 목표로 만들어진 C++ 라이브러리이다. C 언어로 API만 쓸 때에 비해 네이티브 코드 프로그램 개발이 넘사벽급으로 훨씬 더 편리해진다는 건 부인할 수 없는 사실이다(특히 message map 덕분에! ㅋㅋ).

이것의 역사는 윈도우 3.x 시절이던 1992년 무렵으로 거슬러 올라간다. 이때는 MS의 주력 운영체제가 도스에서 윈도우로 바뀌고, 주 개발 언어가 C에서 C++로 이제 막 바뀌던 매우 중요한 과도기였다. 당시 볼랜드의 터보 C의 인지도에 압도적으로 밀리고 있긴 했지만, 마이크로소프트도 MS C라는 컴파일러를 개발해서 팔고 있었고, 이게 7.0 버전부터는 C++ 언어도 지원하기 시작했다.

MFC는 바로 MS C/C++ 7.0부터 도입되었으며, 그 다음부터는 제품명이 그 이름도 유명한 비주얼 C++ 1.0으로 바뀌게 되었다. 당시에는 라이브러리에 Microsoft Foundation Classes라는 거창한 정식 명칭이 없었기 때문에, 그냥 Application Frameworks라고 불렸다. 이것이 바로 AFX의 어원이다.

그래서 오늘날까지도 MFC의 핵심 인클루드 파일 이름은 mfc.h가 아니라 afx.h / afxwin.h이다. 또한 AfxGetApp(), AfxMessageBox() 같은 함수명과, AfxWnd##, AfxFrameOrView##처럼 MFC가 자체적으로 생성하는 윈도우 클래스 이름에도 AFX라는 약어를 찾을 수 있다.

비록 16비트 시절부터 존재하긴 했지만 MFC가 본격적으로 볼랜드 사의 컴파일러와 걔네들 라이브러리를 누르고 인기를 누리기 시작한 건 32비트로 넘어오면서이다. MFC가 첫 도입되었을 때는 C++ 개념을 구현하는 데 드는 특유의 오버헤드가 성능 면에서 문제가 되지 않을까 하는 회의적인 시각이 많았었다. 가령, code bloat으로 인한 용량 증가를 비롯해, 가상 함수 호출이라든가, 윈도우 핸들을 C++ 개체로 연결하기 위한 비용 같은 것 말이다.

워낙 옛날에, C++이 지금과 같은 규격으로 확장되기 전에 개발되던 것이다 보니 MFC는 RTTI를 자체적인 메커니즘으로 구현했으며, 컨테이너 클래스를 템플릿 없이 자체적으로 여러 구현체로 만든 게 있다. CPtrList, CObList 같은 것 말이다. MFC가 처음 개발되었을 때는 C++에 아직 템플릿이란 게 없었기 때문이다. 그리고 그 흔한 namespace조차 쓰지 않았다. 당연히 그때는 namespace가 없었기 때문.

MFC가 드디어 어느 정도 안정화를 이뤄 낸 것은 비주얼  C++ 4.2에서 도입된 MFC 4.2이다(MFC42.DLL). 비록 후속 버전인 비주얼 C++ 5와 6에서 개선과 기능 추가가 있었지만, 이것은 하위 호환성이 완벽하게 유지되는 변화이기 때문에 파일 이름이 동일했고, 이것이 MFC42.DLL이 윈도우 98 이래로 모든 윈도우 운영체제가 기본 내장하고 있는 표준 MFC DLL이 되었다.

오늘날 운영체제가 제공하는 MFC42.DLL은 이제 비주얼 C++ 6.0이 제공하던 클래식 MFC42.DLL과 하위 호환성만 유지되는 superset으로, 비주얼 C++과는 별개로 운영체제가 관리하는 DLL이다. 가령, 윈도우 7의 워드패드와 그림판은 명목상 MFC42.DLL을 사용하지만, 원래 VC6에는 없던 리본 인터페이스를 자기네 MFC42.DLL로부터 가져와서 사용하고 있다.

16비트에서 32비트로 넘어가면서 MFC는 일부 내부 자료구조가 바뀌었다. 특히 handle map은 스레드마다 서로 따로 돌아가기 때문에, 서로 다른 스레드끼리 핸들을 주고받을 때는 MFC 개체가 아닌 핸들을 직통으로 주고받아야 안전하다.

뭐, 이뿐만이 아니라 자체 구현으로 표시하던 toolbar와 status bar가 윈도우 95/NT 3.5부터는 common control이라고 운영체제에 정식으로 편입되었기 때문에, 그걸 그냥 끌어다 쓰는 걸로 내부 구현이 바뀌었다는 것도 첨언하겠다.

비주얼 C++ 6에서 닷넷으로 넘어가면서는 CString 같은 기초 자료형이 MFC가 아닌 ATL이라는 다른 라이브러리로 내부 관할이 바뀌고, 완전히 템플릿 기반으로 바뀌어서 한 코드로 ansi string과 wide string을 모두 다룰 수 있게 되었다. 그리고 DLL의 배포 방식이 변화를 겪기도 했다.

그 뒤 MFC는 2000년대에 들어와서는 이렇다 할 큰 변화가 없었고, 하루가 다르게 발전하는 C# 언어와 닷넷에 비해 MS가 네이티브 개발을 너무 홀대하는 게 아니냐는 우려의 목소리가 나올 정도였다. 특히 MS는 오피스 제품을 주축으로 독자적인 화려한 GUI(메뉴, 툴바 등)를 선보였고 오피스 2007부터는 리본 UI라는 완전히 새로운 물건까지 선보여 왔는데, 이를 모방하여 구현해 주는 MFC 기반 싸제 GUI 라이브러리가 제3자에 의해 미들웨어로 전문적으로 개발되어 판매될 정도가 되었다. 이름하여 GUI 툴킷.

과거 오피스 97/2000까지만 해도 프로그램 비주얼이 운영체제의 그것과 그렇게 큰 차이는 없었다. 그러나 오피스 XP부터 운영체제 기본 프로그램의 비주얼과 그런 오피스(?)급 프로그램의 비주얼은 이질감이 확 생겨 버렸다. 사실은 오피스 XP의 그 하얗고 깔끔한 2D같은 GUI가 윈도우 XP의 전반적인 GUI 디자인이 될 예정이었는데, 그 계획이 수틀리는 바람이 그 오피스 계열하고 운영체제의 알록달록 둥글둥글(?)한 디자인 계열은 따로 놀게 된 거라고 한다.

다음 하편에서는 이 GUI 툴킷과 관련된 MFC의 변천사 이야기를 계속하겠다.

Posted by 사무엘

2012/03/27 08:35 2012/03/27 08:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/660

비주얼 C++ 관련 잡설

1. 비주얼 C++ 한글판

마이크로소프트에서 한글화한 프로그램의 UI에서 이런 저런 오역이 발견되는 건 어제 오늘 일이 아니다. 뭐, “안녕하신가, 힘세고 강한 아침!” 수준의 막장 발번역-_-은 아니지만, 이런 오역이 간간히 발견되는 주된 이유는, 번역자가 해당 소프트웨어가 다루는 분야의 용어를 잘 알지 못해서일 것이다. 그리고 어떤 문장이나 단어가 실제로 프로그램의 어느 부분에서 등장하는지를 모르는 채, 그냥 번역 리스트만 쭉 보면서 아무 문맥 정보가 없이 기계적으로 번역만 했기 때문일 것이다.

마이크로소프트가 개발한 소프트웨어 개발툴 중 비주얼 베이직은 5던가 6 시절부터 이미 한글화가 되었다. 그 반면, 가장 어렵고 하드코어한 개발툴인 비주얼 C++ 6은 한글화되지 않았으며 닷넷에서부터 통합 IDE가 제공되는 과정에서 드디어 한글화가 됐다. 그러나 베테랑 개발자 중에 한글판 IDE를 선호하는 사람은 거의 없으며, 이 점에서는 본인도 마찬가지이다.

옛날에 유니코드라는 것도 없고 PC의 환경이 극도로 열악하던 시절에는 한글판이 대놓고 영문판보다 성능이 열등했다. 텍스트 모드에서 한글 바이오스를 띄웠을 때와 띄우지 않았을 때의 성능 차이는 말할 나위도 없고, 도스 시절에 한글 QuickBasic은 성능은 둘째치고라도 그야말로 퀵라이브러리(qlb) 파일 포맷이 영문판과 호환조차 되지 않던 쓰레기-_-였다.

영문 윈도우 95는 4MB 램에서 그럭저럭 돌리는 게 가능했던 반면, 각종 무거운 한글· 한자 글꼴을 얹어야 했던 한글 윈도우 95는 최하 6~8MB 램이 필요했다. 그것도 어지간한 PC의 메모리가 4~8MB 사이이던 시절에!
난 아직도 기억이 생생한 게, 펜티엄급 노트북에서 IE4를 띄웠는데 빽빽한 영문으로 된 사이트는 비교적 매끄럽게 스크롤된 반면, 빽빽한 한글이 적힌 사이트(그냥 굴림체 비트맵 글꼴 크기)는 스크롤이 상당히 굼떴었다.

그도 그럴 것이 윈도우 세계에서는 '한글'이 그것만 특별 취급해 줘야 하는 문자가 아니었으니, 당시의 도스용 프로그램들처럼 효율적인 조합형 한글 입출력 메커니즘이 쓰이지 않았다. 게다가 한국에서 완성형이 주류 표준이다 보니 다국적 소프트웨어라면 한글을 2350자 내지 11172자의 그림문자처럼 취급할 수밖에 없었기 때문이다.

물론 세월이 흐르고 흘러 지금은 언어에 따른 성능 격차는 없기에 앞서서 측정 자체가 무의미해진 건 사실이다. 지금은 성능 격차 때문에 일부러 영문 원판 소프트웨어를 찾아 쓸 필요는 없다. 그러나 비주얼 C++ 같은 프로그램은 어차피 아무나 쓰는 프로그램도 아니고, 핵심 용어들에 대한 어설픈 번역에 이질감과 거부감이 들어서 한글판을 안 쓴다고 보는 게 타당하겠다.

단적인 예를 들어 보겠다. 아래 스크린샷을 보라.

사용자 삽입 이미지

먼저, output 창에 있는 컴파일 에러 로그를 보자. Illegal case를 '대/소문자가 잘못되었습니다'라고 오역한 건, 비주얼 C++이 처음으로 한글화된 200x 이래로 지금의 무려 2010에서까지 고쳐지지 않았다. 번역자가 C++ 프로그래밍에 전혀 무지하거나, 이 문장이 어느 문맥에서 쓰이는지를 하나도 알지 못한 채 번역했음이 분명하다. 세상에 C++이 컴파일러 차원에서 코드의 대소문자 오류를 분간해 주는 언어였던가. ㄲㄲ

비주얼 스튜디오 2010은 C#에 이어 C++까지도 코드의 오류가 있는 부분에 빨간 점선을 그어 준다. 물론 C++ 코드는 C# 코드보다 분석하기 훨씬 더 힘들기 때문에, 이는 내부적으로 완전한 형태의 컴파일러를 백그라운드로 돌림으로써 상당한 양의 CPU 오버헤드와 디스크 용량을 대가로 치른 끝에 구현된 편의 기능이다.

마우스를 case문 에러가 있는 곳으로 가져가 보면, 에러 메시지가 뜻밖에도 컴파일러가 뱉은 것과는 표현이 다르다. 그런데 '스위치'라고? 이건 case를 대소문자라고 옮긴 것보다는 덜 심각한 오역이지만, 이 역시 번역자가 문장을 제대로 이해를 못 하고 번역한 것 같다. 혹시 기능을 켜고 끄는 물리적인 스위치를 생각한 건 아닐까? 스위치를 음역하지 말고 그냥 'switch문'이라고 옮기는 것이 더 정확할 것이다.

2. 비주얼 스튜디오 2010의 GUI customization

비주얼 스튜디오와 MS 오피스 제품(지금처럼 리본 UI가 도입되기 전)은 그야말로 자신만의 화려하고 강력한 GUI를 갖추고 있었다. 메뉴와 도구모음줄은 운영체제가 자체 제공하는 녀석이 아닌 독자 구현 버전을 썼으며, 정말 과잉 투자 잉여라는 생각이 들 정도로 모든 GUI 구성 요소를 사용자 입맛에 맞게 바꿀 수 있었다. 도구모음줄의 배치는 두말 할 나위도 없고, 등록해 놓을 명령, 그리고 심지어 아이콘 그림과 기능 명칭까지도!

내 기억이 맞다면 이거 원조는 MS 오피스 97이다. BCG나 Xtreme toolkit처럼 이런 GUI 엔진만 짝퉁으로 구현하여 미들웨어 형태로 파는 업체도 응당 있을 정도였다.

이런 GUI 엔진이 탑재된 프로그램은 메뉴에 Tool(도구) - Customize(사용자 지정)라는 명령이 있었고, 이 대화상자는 약간 특이하게 동작을 했다.
보통 modal 대화상자가 떠 있는 동안은, 상위의 응용 프로그램 윈도우는 그 대화상자를 닫을 때까지 전혀 반응을 하지 않게 된다.
그런데 그 Customize 대화상자는 비록 modal 형태이지만, 그게 떠 있는 상태에서 마우스로 도구모음줄을 클릭하거나 메뉴를 누르면 도구모음줄이 반응을 했다. 도구모음줄 아이콘을 드래그하여 배치를 바꾸거나 없애거나, 콤보 상자의 경우 폭을 조절할 수 있고 우클릭하여 아이콘이나 설명문을 고칠 수 있었다.

즉, 평소에 도구모음줄을 우클릭하면, 나타내거나 감출 도구모음줄을 선택하는 메뉴만 뜨지만, Customize 중에 도구모음줄을 우클릭하면 해당 도구모음줄 아이콘을 고치는 더 세부적인 명령이 떴던 것이다.
메뉴에서 자주 쓰는 기능을 도구모음줄에다가도 좀 올려 놓으려면, 메뉴를 연 뒤에 해당 기능을 원하는 도구모음줄에다가 Ctrl+드래그만 하면 끝이었다.

사용자 삽입 이미지

그런데... 그런데... 비주얼 스튜디오 2010은 GUI 엔진이 싹 바뀌면서 저런 예외적이고 특이한 기능을 다시 구현하기가 대략 곤란했는지..
Customize 대화상자와 도구모음줄이 자연스럽게 연동하는 기능이 완전히 없어졌다.
대화상자가 떠 있는 동안은 도구모음줄을 전혀 건드릴 수 없다.

도구모음줄을 고치는 걸 전적으로 대화상자 안에서만 해야 한다.
내가 원하는 명령을 도구모음줄에다가 좀 추가하려고 했는데, 내가 원하는 도구모음줄과 내가 원하는 명령을 일일이 복잡한 리스트에서 찾으면서 정말 불편하고 번거롭기 그지없었다.
그리고 콤보 상자(빠른 찾기, 솔루션 플랫폼, 빌드 configuration 바꾸는 것 등)의 폭을 좀 바꾸려고 했는데 세상에나...
폭을 픽셀 단위 숫자로 입력해야 한다. -_-

사용자 삽입 이미지

예전에는 마우스 드래그로 간편하게 됐던 것이 상당히 퇴보한 게 아닐 수 없다..;;
난 개인적으로 GUI 운영체제에서, 화면으로 결과를 당장 볼 수 있는 값을 숫자 하나 달랑 입력받게 해 놓은 UI를 싫어한다. 가령, 객체를 회전하는 것만 해도 MS 오피스는 회전축을 잡고 마우스로 드래그함으로써 결과를 실시간으로 보면서 쉽게 할 수 있는데, 아래아한글 2007은 각도를 숫자로 입력해야 하고, 만족스러운 각도가 나올 때까지 사용자가 시행 착오를 겪어야 한다.;;

그런데 그런 불편한 방식을 비주얼 스튜디오 2010이 답습한 셈이다.
Customize 기능을 없앨 수는 없으니까, 그냥 이런 형태로 대충 대체 UI를 집어넣은 거라는 인상을 지울 수 없다.;;

딱 하나 좋아진 게 있다면,
예전의 customize 방식은 편리한 대신, 편법 UI인 만큼 오로지 마우스로만 접근 가능하고 키보드로는 하는 게 아예 불가능했는데 이제는 대화상자를 다루는 것이니 키보드로도 얼마든지 가능해졌다는 것.
사실, 가장 이상적인 건 둘을 모두 갖추는 것이긴 한데 이건 비주얼 스튜디오 2010에서 아쉬운 면모가 아닐 수 없다.

아울러 덧붙이자면, VS 2010도 Alt+F11을 눌러서 매크로 편집기를 열어 보면 그건 하나도 안 바뀌었고 예전의 VS 2008 IDE가 거의 그대로 뜬다.

Posted by 사무엘

2011/11/21 08:32 2011/11/21 08:32
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/602

비주얼 C++ 2010 써 보다

* 옛날에 썼던 이 글과 연계되는 내용이다.

비주얼 스튜디오 2010을 드디어 회사에 깔아 봤다. 극심한 뒷-_-북.
인터넷 익스플로러 9만 보고도 “세상에 MS가 이런 UI의 프로그램도 만들다니, 오래 살고 볼 일이다”란 생각을 한 적이 있는데, VS 2010도 과연 그러하다.
개인적으로 시커먼 남색 배색이 별로 마음에 들지는 않다만..;;. 어째 이런 비주얼을 만들 생각을 했을까 싶다.

듣던 대로 IDE의 GUI 껍데기는 밑바닥부터 완전히 바뀌어서 다시 작성되었다.
닷넷 200x 시절은 비록 비주얼은 살짝 다를지언정 그래도 MS 오피스 엔진의 흔적이 남아 있었고 닷넷 초창기 버전인 2002/2003은 아예 오피스 XP의 GUI를 그대로 차용했었는데, 이제 비주얼 스튜디오의 GUI는 오피스와는 전혀 관계 없는 독자적인 엔진 기반이다.
그러고 보니 비주얼 C++ 6은 MFC를 사용하여 오피스와는 관계 없는 독자적인 GUI였는데... ^^;;

윈도우 운영체제의 모든 GUI는 메뉴에서 상하 화살표를 누르고 있으면, 비록 사용 불능(disabled)이라 할지라도 모든 항목이 순서대로 순회된다. 난 이게 MS 사의 전통인가 싶었다. 운영체제의 표준 메뉴부터 시작해 MS 오피스 등 MS에서 만든 역대 제품들을 모두 살펴보기 바란다.
그러나 VS 2010의 메뉴는 불능 항목는 아예 선택되지 않고 skip된다. 이 점에서는 과거 도스용 아래아한글의 동작과 비슷해졌다.

하다못해 이런 사소한 메뉴 GUI의 동작에서부터도 본인은 MS에서 만든 프로그램 같지 않은 이질감이 곧바로 느껴졌다.
덧붙이자면 VS 2010의 메뉴는 언제나 화면이 확 펼쳐지지 Fade나 Slide 같은 애니메이션 효과가 나타나지도 않는 것 같다.

IDE의 로딩 시간과 덩치는 확실하게 크고 아름다워졌다.
단, 인텔리센스는 확실히 예전 버전보다 더 똑똑해진 게 느껴져서 편하다. *.ncb 파일 대신 다른 방식의 인텔리센스 DB를 쓰는데, 역시 프로젝트 하나당 수십 MB씩 용량을 무지막지하게 차지하는 건 변함없다.
닷넷 시절 거의 10년 가까이 사용해 온 Document Explorer 기반 도움말(MSDN) 시스템도 갈아엎었다고 하는데 자세한 내역은 잘 모르겠다. 단, 매크로 IDE는 과거의 비주얼 스튜디오 2008 IDE를 그대로 쓰고 있음.

프로그래머용 에디터에 화면 확대/축소 기능이 생겨서, 단순히 글씨 크기만 바꿀 때는 옵션 대화상자를 꺼낼 필요가 없게 된 건.. 상당히 참신하다. 그래도 조절을 할 수 있으니까 유용하다.
<날개셋> 편집기도 글씨 크기 조절 기능 건의가 지금까지 한두 번 들어온 게 아니니 말이다. =_= (하지만 프로그램의 구조와 개발 방향의 특성상, 실현 가능성은 제로)

뭐, IDE와 GUI 얘기는 여기까지 하고...
비주얼 스튜디오는 2005 이후에 3이 더해진 2008 버전보다도, 2가 더해진 2005나(2003에서 버전업) 2010이(2008에서 버전업) 변화 사항이 많았다.
다만, 2003과 2010은 그 해 4월에 출시되었고 2005는 그 해 말(10~11월), 그리고 2008은 아예 2007년 말에서 2008년 초에 가깝기 때문에 실제 출시 간격은 2년 반에서 큰 차이가 없다고 볼 수도 있겠다.

역사적으로 MS 제품들이 2000년대 중반에 운영체제는 XP와 비스타 사이, 오피스는 2003과 2007 사이, IE는 6과 7 사이에 간격이 굉장히 길었다. 이에 반해 비주얼 스튜디오는 그런 제품들과는 무관하게 버전업이 꾸준히 되어 온 셈이다.

과거 MSVCR71.DLL, MFC71.DLL에 이어, MSVCR100.DLL과 MFC100.DLL도 이젠 그냥 편하게 윈도우 시스템 디렉터리에 들어가 있다. 정말 감개무량하다. VS 2005와 2008이 사용하는 CRT/MFC DLL만(80, 90) 잠깐 winsxs 밑으로 숨었었는데, 그 방식이 배포하기가 너무 불편해서 다시 일반 DLL 로딩 방식으로 되돌아간 것이다.

VC 6의 유물이던 클래스 마법사가 다시 생긴 것도 신선한 충격. 굳이 MFC 기반 프로젝트가 아니어도 유용해 보인다.
하긴, 6 시절까지만 해도 클래스 마법사가 효율적으로 소스를 파싱하라고 메시지 맵에 //AFX_MSG 같은 이상한 주석 부호도 있었는데.. 그게 필요 없어진 게 닷넷부터이다.

VC 2010은 모처럼 C++ 언어 문법도 제법 확장되었으니 이것도 짚고 넘어가지 않을 수 없겠다.

auto와 nullptr은 가뭄에 단비 같은 유용한 키워드이다.
전자는 본인이 예전에도 논평했듯이, 번거로운 타이핑과 typedef를 획기적으로 줄여 준다.
그리고 후자는 숫자로 쓰이는 0과 포인터로 쓰이는 0을 확실하게 구분하여 C++ 함수의 오버로딩 때 모호성을 해소해 준다. explicit과 비슷한 맥락에서 추가되었다고도 볼 수도 있겠다.

다만, 기존 코드와의 명칭 충돌을 최대한 피하기 위해 null이나 NULL, 심지어 nil도 아닌 nullptr로 예약어가 정해졌다는 건 감안할 필요가 있음.
또한, 기왕 auto가 추가됐을 정도면 상위 클래스를 자동으로 가리키는 super 같은 키워드도 C++에 같이 좀 추가하지 하는 아쉬움이 있다. 비주얼 C++은 MS 확장 차원에서 __super가 있긴 한데 말이다.

문득 드는 생각인데, 순수 가상 함수를 선언할 때 쓰이는 0은 숫자에 가까울까, 포인터에 가까울까?
숫자의 성격이 강하다면 0 대신 false를 써도 되겠고, 포인터의 성격이 강하다면 0 대신 nullptr을 쓰면 되겠다. 하긴, true와 false는 진작부터 C++ 예약어로 추가됐는데 말이다. 이제 C++에는 0을 의미하는 키워드가 둘 존재하게 됐다.

뭐, 요약하자면, 덩치가 딥다 커졌는데, 커진 만큼 덩치값 하는 편의 기능도 많고 기능면에서 바뀌고 향상된 것도 많다. 다만, 비주얼은 내 눈에는 여전히 좀 이질적임. ㅋㅋ
간단하게 VC 2010으로 <날개셋> 한글 입력기 프로젝트를 빌드도 해 봤다. 개발용으로는 2010으로 언제쯤 완전히 갈아탈지는 미지수이다.

<날개셋> 한글 입력기는 1.x부터 2.4까지는 VC 6.0을 썼고, 2.5부터 5.3x까지는 6년 동안 VC 2003을 썼다. 그러다가 5.5부터는 지금까지 약 2년간 VC 2008을 쓰는 중. 2005는 64비트 에디션을 빌드할 때만 잠깐 쓰다가 이마저도 2008로 곧 대체됐다. ^^;;

난 개인적으로 비주얼 C++에 대해 실현 가능성이 별로 없는 두 가지 희망 사항이 있다.

첫째, MFC나 플랫폼 SDK 같은 공통 프로그래밍 요소들의 인텔리센스 정보들은, 매번 번거롭게 각 프로젝트별로 중첩해서 들어가는 게 아니라 이미 만들어져 있는 걸 공유할 수 있으면 좋겠다. 이것만 해도 인텔리센스 파일 크기가 엄청나게 줄어들 것이다. -_-;;

그리고 둘째, 운영체제의 legacy known DLL인 msvcrt.dll과 mfc42.dll에다가 바로 링크하는 기능도 좀 있으면 좋겠다. 런타임 dll을 배포하지 않고, static link 하지 않고도 작은 바이너리 배포를 할 수 있게 말이다.

덩치가 커지는 것 자체가 문제가 아니라, '불필요하게' 덩치가 그것도 꽤 부담될 정도로 커지는 게 문제이다. I hate bloatwares. -_-

Posted by 사무엘

2011/08/13 08:11 2011/08/13 08:11
,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/554

프로그래밍 잡설

1. 닷넷 기반 프로그램의 특징:

- 뜨는 데 시간이 좀 오래 걸린다.
- 파일 내부를 들여다보면 전통적인 네이티브 프로그램처럼 kernel32, user32, gdi32 따위가 아니라, mscoree.dll에 대한 Dependency만 있다.
- 생성하는 GUI 윈도우들의 클래스를 보면 WindowsForm10 이런 명칭으로 시작한다.
- 같이 들어있는 DLL들이 '뭐.뭐' 이런 식으로 대소문자가 섞이고 중간에 마침표도 있는 등, 이례적으로 이름이 긴 경향이 있다. 네이티브 EXE/DLL은 그런 식으로 작명되는 경우가, 금지되거나 불가능한 건 절대 아님에도 불구하고, 거의 없다. 유닉스 내지 심지어 도스 시절 8.3 영향을 받은 짧고 암호 같은 영어 알파벳 조합이 아직까지 대세.

유명한 닷넷 프로그램으로는 MS Keyboard Layout Creator, Paint .NET이 있다. 비록 닷넷 기반으로 비주얼 베이직.NET과 C++ managed extension 같은 언어도 있긴 하지만, 그래도 90%이상의 여건에서는 닷넷이 곧 C#이나 마찬가지이다.

게임 자체는 모르겠지만, 최소한 게임과 관련된 툴 정도는 C#으로 만드는 게 충분히 승산이 있는 단계에 이른 것 같다. 스타크래프트의 StarEdit처럼 고객이 사용하는 툴이든, 게임 개발사 내부에서 디자이너나 기획자가 쓰는 툴이든 말이다. C#은 일종의 가상 기계 프레임워크 기반이면서도 로컬 환경 역시 적당하게 잘 공략한 것 같다. 이제 MFC는 덩치가 커져도 너무 커졌고, C#은 빌드 속도 같은 생산성 면에서 C++을 압도적으로 능가한다.

게임 클라이언트에 이어 게임 서버까지 C#으로 만들어 돌리는 날이 과연 올지는 모르겠다. 컴퓨터의 성능이 계속 향상되니까 괜찮을 거라는 말이 있지만, 그래도 과거에 C/C++은 어셈블리와 일대일 대응하는 최소한 네이티브 코드 생성 언어이지 않았던가.
다만, 아직은 C# 프로그램이 네이티브에 비해 느린 건 둘째치고라도, 앞서 말했듯이 좀 무겁다는 인상이 짙게 느껴진다. (뜨는 데 걸리는 시간) 이게 좀 개선됐으면 좋겠다. 듣자하니, MS는 내부적으로는 C# 코드를 산뜻한 네이티브 코드로 빌드해 주는 컴파일러를 보유하고 있다는데..;;

2.
본인, 전공이 전공이다 보니 소위 '국어 정보 처리' 분야의 프로그램들을 좀 접했다. 형태소 분석, 말뭉치 검색 등.
비주얼 C++ + MFC로 만들어진 게 다수이지만 2005년 이후부터는 C#을 쓴 것도 심심찮게 보인다. 다만, '깜짝새'라고 유명한 프로그램이 있는데, 얘는 이례적으로 델파이로 개발됐다.

이런 프로그램들은 그 특성상, 결과 데이터를 마치 스프레드 시트처럼 row-column 형태의 출력하는 경우가 많다. 그런데 순수하게 처리를 하는 비용뿐만이 아니라, 처리가 끝난 결과 데이터를 해당 리스트 컨트롤에다 등록하는 데 걸리는 시간도 만만찮아서 본인은 그게 불만이다. 결과 출력하느라 리스트 컨트롤의 스크롤바가 쫘르륵~~ 변하는 모습을 보고 있으면 좀 민망하다. 불필요한 화면 refresh가 수천, 수만 회 발생하고 있다는 뜻이지 않은가?

대용량의 데이터를 그런 형태로 출력할 때는, owner-draw라든가 virtual list control 테크닉을 써서, 결과 데이터를 일일이 리스트 컨트롤로 복사하는 게 아니라, 그때 그때 출력을 내가 직접 하도록 해야 한다. 이렇게만 하면 프로그램의 체감 동작 속도가 월등히 빨라지며 메모리도 크게 아낄 수 있다.
도스 시절이었다면 리스트 컨트롤 같은 컴포넌트라는 개념 자체가 없었을 터이니 이런 비효율 자체가 존재할 여지가 없었을 것이다. 물론, 소프트웨어의 재활용성면에서 도스는 어차피 빵점인 열악한 환경이니 도스 시절이 마냥 좋다는 건 아니다.

저런 프로그램들이 어떤 여건 속에서 개발되었는지 잘은 모르겠다. 허나, 열악한 자금과 시간에 쫓기면서 공밀레 공밀레 하면서 만들어진 프로그램이라면, 개발자가 아무리 날고 기는 천재 프로그래머라고 해도 답이 없다. 품질을 보증할 수 없고, 이런 자그마한 곳에서의 사용자 배려 따위는 절대로 기대할 수 없다. 이는 개인의 프로그래밍 실력과는 하등 관계 없는 문제이다.

그 반면에 <날개셋> 한글 입력기가 가히 변태적인 수준의 최적화를 자랑하며 개발되고 있는 이유는 시간과 돈에 전혀 구애받지 않고 전적으로 개인의 자아 실현을 위해 만들어지는 프로그램이기 때문이다. -_-;; 언제까지나 그런 태도로 프로그램을 만들 수는 없으니까 그게 문제지만.
이런 문제를 이쪽에 계시는 교수님들도 인지는 하고 있지만, 우리나라 IT 인프라에 전반적으로 딱히 답이 안 보이는 문제이니 어쩔 수 없다.

3.
C/C++ 부류의 type 시스템은 액세스(MS Access)와 비슷하고,
파이썬 부류의 type 시스템은 엑셀(MS Excel)과 비슷하다. 진짜 딱 대응하는 것 같다.

스프레드 시트인 엑셀은 아무 셀에 아무 타입의 데이터나 바로 집어넣을 수 있으며, 그러면 그 형태를 엑셀이 알아서 인식해서 출력해 준다. 날짜는 날짜처럼, 문자열은 문자열처럼, 숫자는 숫자처럼 오른쪽 정렬을 해서.
그러나 데이터베이스 프로그램인 엑세스는 테이블을 설계할 때 모든 애트리뷰트와 각 애트리뷰트에 들어갈 수 있는 값의 타입을 지정해야 하며, 딱 그 값만 넣을 수 있다. 문자열은 길이 제한까지도 생각해야 한다. 정말 딱딱하고 까다롭다.

엑셀은 셀의 값들에 서식도 자유롭게 지정할 수 있고 Undo도 얼마든지 가능하다. 엑세스는 그런 게 없으며, 테이블을 수정한 게 파일에도 바로 반영된다.

그러나 수십, 수백만 개에 달하는 데이터를 검색하고 한꺼번에 고치고, 테이블 간의 관계를 분석하는 동작에서 엑셀과 엑세스의 효율은...;; 더 설명이 필요하지 않을 것이다.

그럼에도 불구하고 엑세스 급의 전문적인 성능이 필요한 경우는 매우 드물다. 일반 사용자들은 어지간한 중소 규모의 데이터나 다룰 것이고 이때는 친근한 엑셀이 대부분의 경우 훨씬 더 도움이 될 것이다.

4.
PC 파워 유저라면, 윈도우용 EXE 파일에는 리소스라는 별도의 데이터 섹션이 있다는 걸 알 것이다. 윈도우용 EXE는 이례적으로 자체 아이콘을 갖춘 파일 포맷인데, 그것도 바로 리소스라는 형태로 들어있다. 운영체제는 EXE/DLL의 리소스를 조작하는 API를 제공하며, 이를 이용하면 프로그램의 메뉴, 메시지 문자열을 고쳐서 허접하게나마 프로그램을 한글화(자국어화)할 수도 있다. 물론, 모든 프로그램에 그런 테크닉이 통하는 건 아니지만.

이 일을 프로그래밍을 통해서 하려면 BeginUpdateResource, UpdateResource, EndUpdateResource라는 함수를 쓰면 된다. 다만, 윈도우 9x는 이 기능을 지원하지 않았으며 그건 NT에서만 지원됐다. 그런 기능을 어차피 일반 사용자가 쓸 일은 없었을 테니까.
그런데 신기하게도 그 당시 윈도우 9x에서 실행된 비주얼 C++ 6은, 32비트 EXE/DLL의 리소스를 고칠 수는 없었던 반면, 16비트 EXE/DLL의 리소스를 고쳐서 저장할 수는 있었다.

윈도우 API를 쓴 건지, 아니면 16비트 바이너리는 비주얼 C++의 자체 기능으로 파일을 건드렸는지는 잘 모르겠다. 다만, 16비트 바이너리와 32비트 바이너리는 리소스를 저장하는 방식이 상당히 다르기 때문에 아마 자체 기능이 아니었겠나 싶다. 근본적으로 32비트 바이너리는 wide character 유니코드를 사용하지만 16비트 바이너리는 그렇지 않다. 그래서 과거에 윈도우 3.1에다가 Win32s를 설치하면 각종 시스템 DLL뿐만이 아니라 유니코드 변환 테이블인 NLS 파일들도 잔뜩 설치됐던 것이다.

Posted by 사무엘

2011/07/06 08:09 2011/07/06 08:09
,
Response
No Trackback , 10 Comments
RSS :
http://moogi.new21.org/tc/rss/response/536

비주얼 C++ 개발자에게 F12는 무척 특수한 의미를 갖는 단축키이다. 커서가 가리키고 있는 명칭(함수, 변수, 클래스 등~)이 선언되어 있는 위치로 바로 이동해 주는 기능이기 때문이다. Find in Files와 더불어 복잡한 소스 코드를 분석할 때 없어서는 안 되는 기능이다.

또한 Alt+F12는 Symbol 탐색기이다. 무수히 많은 파일들을 무식하게 문자 단위로 검색하는 게 아니라 최적화된 symbol 데이터베이스만을 뒤지기 때문에, 명칭만의 출처를 아주 빠르고 똑똑하게 찾을 수 있다.

사실 이 기능은 비주얼 C++ 6.0에도 있었고, 심지어 더 이전 버전도 갖추고 있었다. 그러나 그때는 이 기능이 활발하게 활용되지는 못했다.
이런 고급 기능을 사용하려면 프로그램의 전체 빌드를 Browse 정보를 남겨 놓는 방법으로 특수하게 다시 해야 했기 때문이다. 그리고 매번 빌드할 때마다 그 Browse 정보도 업데이트해야 했다. 그러므로 빌드 시간도 증가.

원래 C/C++이라는 언어 자체가 빌드 속도가 느린 데다, obj, pch, ncb 등 온갖 잡다한 output을 많이 남기는 걸로 악명 높은 언어이다. 언어의 범용성 보장이라든가 강력한 네이티브 코드 생성을 위해서 어쩔 수 없는 면모도 물론 있긴 하나, 현대의 언어들과 비교했을 때 생산성이 무척 떨어지는 건 사실. 그런데 그것도 모자라서 빌드 오버헤드까지 감수하면서 별도의 Browse 정보를 생성해야 한다니. Browse 기능을 쓰는 사람이 많을 수가 없었다.

내 말이 믿기지 않으면, 비주얼 C++ 6 갖고 계신 분은 프로젝트 하나 만들어서 아무 명칭에다 대고 F12를 눌러 보라. Browse 정보를 생성할 건지 묻는 질문부터 먼저 뜨는 걸 볼 수 있을 것이다.

그러다가 비주얼 C++ .NET이 출시되면서 장족의 발전이 이뤄졌다. 별도의 Browse 정보를 만들 필요가 없이, 빌드 한 번만 하고 나면 명칭 조회와 탐색이 아무 프로젝트에서나 가능해진 것이다. 굉장히 편리해졌다.

사실 이건 어찌 보면 자연스러운 귀결인 게, 비주얼 C++ 6.0부터는 어차피 인텔리센스 기능이 초보적인 수준이나마 추가됐기 때문이다. 함수의 원형이 마우스의 풍선 도움말로 뜨고 명칭을 자동 완성해 주는 기능은 Browse 기능과 성격이 상당수 비슷하지 않은가?

기술적으로 어떻게 변했는지 정확하게는 모르지만, 본인 생각에는, 둘이 서로 따로 DB를 구축하면서 따로 놀던 게 닷넷부터는 동일한 인텔리센스 데이터를 공유하면서 명칭 조회 기능과 인텔리센스가 모두 동작하도록 바뀌었지 싶다. 그래서 그런지, 편리해진 대신에 닷넷 초창기 버전은 과거의 6.0에는 있던 기능이 잠시 사라진 것도 있었다.

바로 함수에 대해서 Caller/Called by 그래프를 그려 주는 기능이다. 이 함수가 또 어떤 함수를 호출하는지 쭉쭉~ 아니면 이 함수를 사용하는 함수는 무엇이 있는지 쭉쭉~

그런데 인텔리센스 정도 구현하는 데는 명칭 자체에 대한 DB만 구축하면 되지, 명칭과 명칭 사이의 각종 인과관계를 따질 필요는 없지 않은가. 그래서 비주얼 C++ 2003(닷넷)에는 잘 살펴보면 저 기능을 어디에도 찾을 수 없다. 본인의 가설을 뒷받침하는 증거 중 하나이다.

잠시 없어졌던 그 기능은 비주얼 C++ 2005부터 완전히 부활했다. 인텔리센스 자체가 버전업을 거듭하면서 굉장히 강력해졌기 때문이다. 2003부터는 #define 심볼과 템플릿도 지원되기 시작했고, 2005/2008부터는 함수 포인터도 지원되기 시작했다. 예전에는 프로젝트를 별도로 빌드해서 파일로 조회를 해야 했던 정보가, 지금은 컴퓨터가 좋아진 덕분에 실시간 업데이트와 조회가 가능한 존재로 바뀌었다.

비주얼 C++ 2010은 듣자하니 인텔리센스 엔진이 또 완전히 바뀌었고, C#이나 베이직 같은 ‘쉬운 언어’에서나 지원되던... 빨간 선 기능(워드 프로세서의 맞춤법 검사기처럼.. 문법에 틀린 부분)이 흠좀무스럽게도 C++에도 도입되었다고 하더라.

인간의 프로그램 개발 환경의 생산성 개선을 위한 노력은 오늘날에도 계속되고 있다. ㄲㄲ

Posted by 사무엘

2011/06/07 19:10 2011/06/07 19:10
Response
No Trackback , 9 Comments
RSS :
http://moogi.new21.org/tc/rss/response/522

대학원에 간 뒤부터 컴퓨터나 프로그래밍 쪽 글은 눈에 띄게 줄고, 확실히 언어 쪽 글이 늘었다. 물론 철도 글은 예나 지금이나 비슷한 빈도로.. ㅋㅋㅋ
그래도 언젠가 한 번쯤 이런 글을 올리고 싶었다.

비주얼 C++ 4.2는 본인이 고등학교에 진학하고서 도스용 프로그램으로 정올 공모를 한 번 마친 후, 그때부터 공부하기 시작한 툴이다. 이때 윈도우 API, MFC, 심지어 C++ 객체 지향 개념까지 전부 뭉뚱그려서 동시에 공부를 시작한 셈이었다.
그로부터 10년이 지난 지금까지도 비주얼 C++은 나의 소중한 친구이고 내 마음의 고향이다. ^^;; <날개셋> 한글 입력기 1.0이 VC++ 4.2로 개발되었다.

참고로 4.2 버전은 4.0 버전이 몇 차례 마이너 업그레이드를 거친 것이었다. 4.2가 따로 4.0처럼 별도의 패키지로 출시되지는 않았으며, MSDN 구독자에게만 비공식적인 경로로 배포되었다고 한다. 이 점에서 4.2는 윈도우 95로 치면 마치 OSR2 업그레이드 에디션과 비슷한 위상이다.
지금은 윈도우든 개발툴이든 오피스든 MS에서 나오는 제품들은 다 서비스 팩이라는 개념으로 업데이트 방식이 통일되었지만 말이다.

그러나 4.2라는 버전은 굉장히 의미가 크다. 윈도우 운영체제가 시스템 차원에서 MFC 라이브러리의 하위 호환성을 보장해 주고 있는 최후 버전이 4.2이기 때문이다. 그 이름도 유명한 MFC42.DLL이다. MFC40.DLL이 아니다.

사용자 삽입 이미지

(<날개셋> 한글 입력기 1.0이 바로 윈도우 95 + 800*600 화면 + 비주얼 C++ 4.2 환경에서 개발됐다.)

그 전부터도, PC 환경에서 이제 윈도우가 대세로 넘어갔으니 윈도우 프로그래밍을 공부하려고 마음을 안 먹은 건 아니었다. 그러나 그때는 비주얼 베이직이나 델파이, C++ 빌더처럼 RAD 툴 수준에 머물러 있었다. 그러던 차에 접한 비주얼 C++은 굉장히 충격적이었다.
이 툴로는 다른 툴과는 달리, 운영체제와 직통으로 대화하고 다른 이상한 런타임이 필요하지 않은 가볍고 빠른 프로그램을 만들 수 있었기 때문이다.

비주얼 C++ 4.2 자체도 요즘 최신 버전에 비하면 정말 미치도록 작고 가볍다. ^^;;; 도움말은 RTF 기반이었고, C/C++ + 윈도우 API + MFC 레퍼런스를 전부 합해서 용량이 150MB 남짓밖에 안 했다. 그 당시 왼쪽의 class view는 실시간 업데이트가 되지 않았으며, 소스 코드를 저장해야 업데이트 됐다. ^^;;;
또한 프로그램 파일들이 압축되지 않은 형태로 CD에 그대로 들어있었기 때문에, 프로그램을 설치하지 않고도 CD에서 곧바로 MSDEV.EXE를 실행해서 프로그램을 실행할 수도 있었다. 물론 전기능을 제대로 활용할 수는 없었지만.

한동안 MS 오피스와 비주얼 C++은 요즘 서울 버스 색깔처럼 빨-노-초-파가 어우러진 4색 고리 모양 아이콘을 사용해 왔다. 4.2도 그랬다. 그런데 2010 버전은 둘 다 단색 아이콘으로 돌아갔으니 이 또한 흥미로운 점. 오피스는 노랑-주황색 사각형 창 4개 모양이 됐고, 비주얼 스튜디오(C++ 포함)는 보라색 ∞ 모양이 돼 있다.

세월이 흘러, 현재 <날개셋> 한글 입력기는 9개 모듈을 모두 비주얼 C++ 2008로 개발되는 중이다. 그러나 타자연습과 파워업은 적극적인 개발보다는 유지 보수만 하는 만큼 여전히 2003을 사용 중이다.

Posted by 사무엘

2010/10/29 16:10 2010/10/29 16:10
,
Response
No Trackback , 9 Comments
RSS :
http://moogi.new21.org/tc/rss/response/400

비주얼 C++ 2010 외

※ auto keyword

지금까지 signed와 더불어서 C/C++의 주요 '유명무실' 사문 예약어이던 auto가 비주얼 C++ 2010에서는 완전히 새롭게 거듭날 예정이다.
auto는 그 변수에 초기화해주는 값이 나타내는 타입을 그대로 부여해 준다. 즉,

int a=5; (...) auto b=a; 라면 b는 int형이 되고
vector<int> arr; auto itor=arr.begin(); 이라면 itor의 타입은 vector<int>::iterator 가 된다.

그래서 말 그대로 auto는, 뒤에 나오는 대입값을 보고 자료형을 '자동'으로 알아서 판단하라는 의미가 된다.
이런 게 언제 C++ 표준으로 상정됐는지는 모르겠는데, 기능과 문법을 만들어 놓은 방식이 정말 기발하고 참신하기 그지없다.
이 키워드 하나가 수많은 번거로운 자료형 하드코딩 타이핑 내지 typedef들을 예방해 주리라 기대된다.

당연한 말이지만 auto 자체는 sizeof 같은 연산자의 피연산자가 될 수 없다. 또한 auto가 무슨 비주얼 베이직의 variant 타입처럼 아무 자료형이나 수시로 집어넣을 수 있는 타입을 의미하지는 않는다.
auto 형으로 선언되는 개체나 변수는, 마치 참조자를 선언할 때처럼 반드시 선언과 동시에 값 대입 내지 초기화가 되어야 할 것이다.
C++은 함수의 인자 개수와 인자의 자료형으로만 오버로딩을 구현하지, 함수의 리턴값으로 오버로딩을 구현하지는 않기 때문에 이런 기능을 모호성 없이 구현할 수 있는 것이다.

이 외에 다른 이상한 C++ 문법도 도입되고 C++ 라이브러리 쪽에도 무슨 변화가 있는데 그건 잘 모르겠고,
프로젝트 파일 포맷이 또 바뀔 예정이라고 한다.

※ 비주얼 C++ 프로젝트 파일

여기서 잠깐 역사 수업. 비주얼 C++ 프로젝트 파일의 역대 계보는 다음과 같다.

1기 *.vcp는 16비트 1.x 초창기 시절에 쓰였다.
2기 *.mdp는 32비트 통합 IDE인 Developer Studio 초창기 시절인 4.x에서 쓰였다. 세월이 세월이니만큼, 1기와 2기는 지금은 거의 찾을 수 없는 전설의 파일 포맷이 돼 있다.
3기 *.dsw와 *.dsp는 드디어 여러 프로젝트를 한데 묶어 관리하는 워크스페이스라는 개념이 도입된, 5와 6 두 버전에서 쓰였다.
그 후 닷넷급이라 할 수 있는 비주얼 C++ 200x에 가서는 4기인 *.sln, *.vcproj 방식이 등장했다. 비주얼 베이직/C++/C# 모든 언어들의 프로젝트 사이에 일관성이 생겼으며 워크스페이스라는 명칭이 솔루션으로 바뀌었다. 그리고 프로젝트 파일은 내부 구조가 XML 형태로 바뀌었다.

이제 프로젝트 파일의 내부 구조가 또 바뀔 일은 없을 거라고 생각했는데 2010에서는 vcxproj라고 또 바뀔 거라고 하니 이게 웬일?
설마 MS 오피스 2007처럼 또 zip 압축을 하는 건 아닌가 모르겠다.
하지만 개발툴의 프로젝트 파일은 소스 버전 관리의 편의성 같은 이유도 있고 해서 다들 plain text 방식으로 저장하지, 바이너리 방식을 쓰지는 않을 텐데 말이다.

더구나 개발툴의 버전이 바뀔 때마다 각종 컴파일러 옵션들은 시시때때로 추가되거나 삭제, deprecate되기도 하기 때문에, 이런 프로젝트 파일들은 유연성, 하위 호환성, 확장성을 최대한 유지하는 게 짱이다. 즉 plain text가 정답이라는 뜻이다.

경험상 비주얼 C++ 2005하고 2008은 프로젝트 파일 포맷이 거의 차이가 없다.
sln과 vcproj 파일 앞줄에 있는 버전 번호만 1 줄여 주면, 2008로 만든 프로젝트도 2005에서 아무 문제 없이 바로 읽어들일 수 있다.

※ 비주얼 C++ 6.0이 나온 지 좀 있으면 벌써 12주년

얘기가 여기까지 왔는데 또, 애증이 교차하는 비주얼 C++ 6.0 얘기를 하지 않을 수 없다.
무려 11년 전엔 1998년에 출시되었고 아직까지도 애용되고 있는 소프트웨어로는 스타크와 더불어 양대 산맥이 아닌가 생각된다.
너무 구닥다리가 되어 외형이 후져 보이고(비록 당대로서는 MS 오피스 97 스타일의 새끈-_-한 UI였지만),
64비트 지원 안 되고 최신 하드웨어 기술 및 C++ 표준이 반영 안 돼 있는 것 자체만 빼면 정말 잘 만든 물건이긴 하다.

가끔은 6.0 특유의 그 클래스 마법사가 그리워질 때도 있다.
MFC는 이제 <날개셋> 타자연습 소스 열어볼 때 말고는 별로 접할 일도 없어졌구나.

그 비주얼 C++이 곧 있으면 연도도 2010이고 버전 번호로도 10.0이 나올 예정이다. 감회가 새롭다.
참고로 비주얼 C++ 2005는 2005년 하반기에 나왔지만 2005라는 타이틀이 붙은 반면,
2008은 비슷한 2007년 하반기에 출시됐지만 1이 더해진 2008이라는 타이틀이 붙었다.

※ 여자 프로그래머

7월 1일.. 경의선 전철 개통, 용인-서울 고속도로 개통, 거기에다 비정규직법 상정 2주년-_- 등 여러 굵직한 일이 많았는데, 나도 이제 병특 끝난 지 1주년이 됐다.
그리고 직장 생활 경력이 3년을 넘어갔다. 최소한 말단 신입사원 딱지는 떼는 짬밥이 됐고, 주임/대리급을 바라보는 신분이다. 하지만 옛날 회사나 지금 회사나 여전히 제일 나이가 어리고 내 밑으로 신입을 대한 적이 없으니, 예나 지금이나 늘 막내이다.

그리고 내가 지금까지 다닌 회사에서 여자 개발자를 본 적은 전혀 없다.
IT 회사라고 해도 여직원 하면 오로지 디자인, 기획 아니면 회계/경리이다. 개발자가 여자인 경우는.. 글쎄다.
하지만 외근 나간 연구소에서는 그래도 비주얼 C++ 띄워 놓고 코드와 씨름하고 있는 여자분들을 주변에서 여럿 볼 수 있어서 인상적이었다.

차라리 학교에 있을 때는 그런 모습을 심심찮게 볼 수 있었다. 내가 나온 학교는 공대 중에서 성비가 상당히 균형 잡힌-_-;; 편에 드는 곳이었으며, 전산과 역시 예외가 아니었기 때문이다.
하지만 나는 학교 시절엔 과 친구들하고 거의 어울리지 않고 동아리 같은 것도 안 하고 지냈기 때문에 그런 학우들로부터는 이렇다할 '임팩트'를 받지 못했다.

여직원하고 "아.. 그 땐 이런 함수를 쓰면 돼요"
"이 클래스는 여기서 상속 받았고 이 가상 함수는 이런 용도로 오버라이드하면 됩니다. 대략 이렇게 구현을 하면 어떨까요?"
"아 그렇게 생각해 보니 이렇게 짜면 버퍼 오버런이 우려되고, 멀티스레드 환경에서는 잠재적으로 또 문제가 있겠군요"
이런 이야기를 나눈다면.. 졸라 감회가 새로울 것 같다. 태어나서 이성하고 그런 얘기는 한 번도 한 적이 없으니까. =_=

하긴, 부부 교사도 있고,
커플이 나란히 코레일에 입사하여 기관차 운전 연수를 받던 부부 기관사도 봤는데, (촬영 당시 곧 결혼 예정이라고 쓴 걸 봤음)
부부 개발자라고 없을 이유는 없으리라 생각한다. -_-

Posted by 사무엘

2010/01/11 10:10 2010/01/11 10:10
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/86

« Previous : 1 : 2 : 3 : 4 : 5 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  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        

Site Stats

Total hits:
2663464
Today:
639
Yesterday:
1553