[Effective C++]컴파일러 경고를 지나치지 말자

그 밖의 이야기들, 첫 번째 이야기

Posted by SungBeom on January 10, 2020 · 3 mins read

컴파일러 경고의 의미

C++의 경우에는 코드가 어떤 것인가에 대해 컴파일러 제작자가 여러분보다 더 잘 이해하고 있기를 기대하기는 힘듭니다. 예를 들어 코드 하나를 보도록 하겠습니다.

1
2
3
4
5
6
7
8
9
class B {
public:
    virtual void f() const;
};
 
class D: public B {
public:
    virtual void f();
};
cs

가상 함수인 B::f를 D::f에서 재정의(redefine, 오버라이드)하겠다는 의도인데, 여기에 실수가 숨어 있습니다. B 클래스의 f는 상수(const) 멤버 함수이지만, D 클래스의 f는 괄호 뒤에 const가 붙어 있지 않습니다. 컴파일러 중 하나는 다음과 같은 경고가 나오게 됩니다.

1
warning: D::f() hides virtual B::f()
cs

위 경고는 가볍게 넘겨서는 안 됩니다. 컴파일러는 지금, B에서 선언된 f가 D에서 재선언된 것이 아니라 아예 가려졌다는 말을 하고 있는 것입니다. 이 경고를 무시하고 지나갔다가는 프로그램이 원하지 않는 방향으로 흘러갈 것입니다.

컴파일러에서 내주는 경고 메시지들에 어느 정도 익숙해지고 나면, 이 외의 다른 메시지들도 어떤 뜻으로 나온 건지를 슬슬 이해하는 수준에 오게 됩니다(눈에 보이는 것과 실제 뜻이 너무 자주 다르다는 게 문제죠). 이러한 경험이 웬만큼 쌓이면, 어떤 경고는 넘어가도 되고 어떤 경고는 없애 주어야 하는지를 선택할 수 있는 공력도 쌓입니다. 물론, 최고 경고 수준을 걸더라도 경고 메시지 없이 컴파일되는 코드를 작성하는 것이 일반적으로 더 좋은 실천법입니다. 어떻게 했든 정말 중요한 점은 경고 메시지를 없애기 전에, 그 경고가 여러분에게 알리려는 바를 정확히 이해해야 한다는 것입니다.

컴파일러 경고는 제작사의 고유 선택에 따라 달라지는 것이기 때문에, 이것만큼은 태생적으로 구현별 의존 사항이란 사실을 잊지 마세요. 그렇기 때문에 여러분이 저지른 실수를 컴파일러가 대신 잡아주는 것만 믿고 프로그래밍에 임하는 자세는 좋지 않습니다. 이름을 가리는 위의 예제 코드만 봐도 그런데, 어떤 다른 컴파일러의 경우에는 이 코드에 대해 경고를 띄우지 않습니다.


정리

컴파일러 경고를 쉽게 지나치지 맙시다. 여러분의 컴파일러에서 지원하는 최고 경고 수준에도 경고 메시지를 내지 않고 컴파일되는 코드를 만드는 쪽에 전력을 다 하십시오.
컴파일러 경고에 너무 기대는 인생을 지양하십시오. 컴파일러마다 트집을 잡고 경고를 내는 부분들이 천차만별이기 때문입니다. 지금 코드를 다른 컴파일러로 이식하면서 여러분이 익숙해져 있는 경고 메시지가 온 데 간 데 없이 사라질 수도 있습니다.