타입 변환에 문제가 발생해 런타임 오류가 나는 걸 발견하여, C++ 컴파일러의 Warning level을 3에서 4로 올리기로 결정했다. 전부터 생각만 해오던 일을 어제 문제가 불거지고 나서야 실천에 옮기게 됐다. 서버 팀원 거의 전부가 기하급수적으로 늘어난 경고를 줄이느라 고생했는데, 만 하루가 가까워진 지금까지도 계속 작업을 하고 있다. 그래도 6000개가 넘던 경고 메시지를 대폭 줄여 지금은 80개 수준으로 뚝 떨어뜨렸다. 만 하루가 지나기 전에 모두 끝낼 수 있을 듯 하다.
이 일을 하다 보니 처음엔 사소한 문제라 생각했던 메시지가 실제론 중요한 의미를 전달한다는 걸 새삼 깨달았다. 가장 흔한 문제 중 하나가 사용하지 않는 매개변수이다. 별로 대수롭지 않게 여기고 UNREFERENCED_PARAMETER
로 묶어버리기 쉬운데, 그러지 말고 코드를 좀더 들여다 봐야 한다. 매개변수를 쓰지 않는 이유가 무엇일지 관찰하고 생각해볼 필요가 있다.
처음에는 매개변수가 필요했지만 나중에 요구사항이 바뀌었다면 더 이상 매개변수를 유지할 필요가 없다. 메서드 시그니처를 바꾸는 게 현명하다. 메서드가 제대로 구현 안 된 것일지도 모른다. ErrorCode를 매개변수로 받아서 아무런 일도 안 한다면 문제가 있는 게 아닐까 의심해볼만 하다. 빈 메서드이거나 별다른 일을 안 하는 메서드일 때도 있는데, 이런 경우에는 해당 코드가 다른 곳에서 쓰이고 있는지, 의미 있는 일을 하는지 확인해봐야 한다. 만약 그렇지 않다면 코드를 지우는 편이 좋다. 애써 짠 코드를 지운다는 게 불편할 수도 있는데, 어차피 소스 관리 저장소에 모든 내역이 저장되므로 언제라도 되살릴 수 있다. 괜히 코드를 복잡하게 만들어서 다른 사람에게 두통을 유발해선 곤란하다.
또 자주 발생하는 문제 중 하나로 signed/unsigned mismatch를 꼽을 수 있다. unsigned int로 선언된 변수를 사용할 때 특히 주의해야 하는데, 유효하지 않은 값을 표현하려고 -1로 초기화하는 경우가 많다. -1과 같이 특정 상수 값을 하드 코딩하는 일은 없어야 하는데, INVALID_XXX 를 정의해서 쓰는 편이 역시 좋겠다.
초기화는 했는데 참조하는 곳이 없는 변수 문제는 비교적 간단해서, 코드를 삭제하면 그만이다. 대체로 코드를 유지보수하는 과정에서 생긴 부가물에 불과하기 때문이다.
외부 라이브러리에서 발생하는 경고는 어쩔 수 없을 때가 많다. 오픈 소스 라이브러리라면 직접 코드를 수정해도 되겠지만, 후에 새 버전으로 갈아탈 때 똑같은 문제가 발생하기 딱 좋다. 차라리 라이브러리 헤더 파일을 include하는 부분에 경고를 끄는 옵션을 주는 편이 속 시원하다. 그렇긴 해도 어떤 문제인지는 살펴봐야 하는데, 단순한 경고가 아니라 라이브러리의 버그일 수도 있기 때문이다.
이 외에도 다양한 경고 메시지가 등장하는데, 이를 자세히 들여다 보면 무심코 지나쳐버린 버그를 수두룩하게 찾아낼 수 있다. 최선의 대처는 경고 수준을 최대로 높이고, 경고를 오류로 처리하도록 컴파일러 옵션을 조정하는 것이다.
birdkr님의 이 글(http://mypage.sarang.net/tt/226)과도 맥락이 약간 닿아 있네요. 저도 필요없는 코드는 그때그때 지우자는 의견이에요. 특히 아깝다고 코드를 주석처리 하는 일은 삼가야 할 것입니다.
저희는 매주 한 번 워닝 데이(Warning Day)라고 해서 30분씩 워닝을 잡고 그 직후에 프로그램팀 회의를 해서 결과 발표를 했는데 효과가 좋았어요. 지금은 흐지부지되어서 워닝 데이 행사를 하지 않고, 또 워닝도 다시 증식하고 있지만 말이죠.
Captcha가 “sent”네요!
저희는 이번에 경고가 사라지는 즉시 경고를 오류 처리할 것 같습니다. 이렇게 할 때 골치 아픈 부분이 뭐냐 하면, 구현 중인 코드라서 경고가 발생할 때입니다. 이 경우엔 #pragma message를 사용해서 잊어먹지 않도록 해놓고 그 부분만 경고를 억제하는 식으로 가면 될 것 같습니다.