우리 회사 제품 코드는 크게 커밋 정책이 두 가지로 나뉘어져 있다. 아무나 손쉽게 커밋할 수 있는 공간과 내가 리뷰를 한 다음에 머지 해주는 공간이다. 당연히 전자는 빠르고, 새로운 것들이 손쉽게 추가되는 반면 후자는 더디고 어렵게 작업된다. 프로그래머 입장에서는 후자의 경우 빠꾸(리젝) 당하는 일도 많기 때문에 얼마간 자존심이 상하는 지점이기도 하다. 하지만 난 이런 정책이 우리 제품 코드를 보다 안정적이면서 빠르게 변화할 수 있도록 만들어 준다고 생각한다.
가끔, 대체로 어떤 문제가 발생했을 때, 내가 리뷰하지 않은 코드들에 대해서도 검토하는 일을 하는데 어제도 그런 일이 있었다. 그런데 생각보다 그 부분이 나에겐 다소 충격이었다. 비슷한 상황에 빠질 많은 초보 프로그래머에게 도움이 될 것 같아서 여기에 내용을 조금 옮겨 본다.
#0
첫 번째 부분은 argc, argv였다. 윈도우 창을 띄우는 WinMain을 가진 프로그램이었는데, 프로그램 동작 과정 중에 커맨드라인 파싱 작업이 필요했던 것 같다. 그 프로그래머는 argc와 argv를 얻기 위해서 WinMain의 lpszCmdLine을 파싱하는 코드를 WinMain 내부에 작성해 두었다. 나중에 사용할 곳도 없지만 lpszCmdLine의 부족한 부분을 메우기 위해서 argv[0]는 GetModuleHandle을 사용해서 추가해주는 일도 잊지 않았다.
내가 충격을 받은 점은 다음과 같은 사실이었다. 1) 그 복잡한 파싱 for 문을 왜 함수로 빼지 않았을까, 2) 그 복잡한 파싱 for 문에 왜 커맨드 라인 파싱에 대한 일체의 고려도(따옴표, 역슬래시같은) 되어 있지 않을까? 3) 왜 이렇게 단순화한 버전을 만들면서 이미 다른 사람이 만들어 둔 내용을 사용하지 않았을까?
즉, 결론은 이랬다. 그 파싱 구문들은 굉장히 부적절하고 아주 많은 경우에 잘못된 파싱 결과를 가져오는 코드였다. 실제로 그 프로그램은 argv[1]만 필요로 하기 때문에 심지어는 lpszCmdLine을 직접 평가하는 작업이 더 적절했을 수도 있다. 이런 여러가지 가능성을 제쳐두고 그 프로그래머는 아주 조악한 코드를 자신이 직접 만드는 길을 선택했다.
argc, argv가 필요한 윈도우 프로그램을 만든다면 __argc, __argv, __wargv 같은 좋은 지원 도구들이 있다. 직접 만들 필요가 없다. 이미 검증된 파싱 루틴을 통해서 우리가 원하든 원하지 않든 WinMain이 시작되는 지점에 이미 그 데이터는 우리가 사용할 수 있도록 모두 준비되어 있다. 그러니 그저 가져다 쓰기만 하면 된다. 바퀴를 새로 만들고 이미 다 파싱해 놓은 걸 다시 또 파싱하겠다고 호기를 부릴 필요는 없다.
#1
내가 두번째로 충격을 받은 부분은 한 곳이 더 있었는데 아래와 같은 코드였다.
if(!((__argc == 2) || (__argc == 3)))
도대체 드 모르간의 법칙을 생각나게 하는 이 코드는 무엇일까? 이 코드를 이해하기 위해서는 얼마간 에디터의 도움이 필요했다. 마지막 괄호를 지웠다 다시 썼을 때 에디터가 그 닫기 괄호가 어디에 매핑되는지를 알려주었기 때문이었다. 에디터의 도움이 없었다면 난 다시 스페이스를 사용해서 이 조건문의 실제 의미를 일일이 파악해야 했으리라.
if(__argc !=2 && __argc !=3)
대체로 많은 경우에 괄호가 없도록 조건문을 구성하는 것이 훨씬 읽기 쉬운 코드를 만든다. 위 코드는 에디터의 도움이 없이도 쉽게 의미하는 바를 눈치챌 수 있다.
if(__argc < 2)
의미를 고려한다면 그 조건문은 위와 같이 더 단순화 될 수도 있다. 왜냐하면 그 코드는 argv[1]에 접근 할 수 있는지를 검증하기 위한 용도로 사용되고 있었기 때문이다.
#2
같은 현상을 설명하는 두 개의 주장이 있다면, 간단한 쪽을 선택하라
given two equally accurate theories, choose the one that is less complex
오컴의 면도날이라는 말이 있다. 난 이 말이 프로그래밍에도 적용된다고 생각한다. 대부분의 경우에 간단한 쪽을 선택하는 편이 읽기도 좋고, 단순하며, 안정적인 좋은 코드를 만든다. 그래서 래리 월(펄의 창시자) 아저씨가 최고의 프로그래머 덕목 중 하나로 게으름을 꼽았는지도 모르겠다. 게으른 사람은 적어도 남들이 만든 걸 또 만들거나, 단순한 걸 두고 복잡한 걸 선택하지는 않을 테니 말이다.