본문 바로가기

TIP

[C#] 코드의 재발견, Code Analysis

반응형
[C#] 코드의 재발견, Code Analysis

서우석(한국과학기술원)   2005/12/06 09:29:02 AM
[지디넷코리아]코드를 작성하는 개발자가 자신이 작성한 코드에 대한 정보를 얻을 수 있는 방법을 크게 두가지로 나눌 수 있다. 첫 번째 방법은 정적(static) 분석 방법이며, 다른 방법은 동적(dynamic) 분석 방법이다. 정적 분석 방법은 코드를 실행하지 않고 코드를 분석하는 것으로 주로 컴파일 수준에서 코드를 분석하게 된다. 예를 들면, 코드의 구조를 비주얼하게 보여주는 기능이 이에 해당한다. 반면에 동적인 분석 방법은 코드를 실행함으로써 얻은 결과를 보여주는 것으로 호출 트리(call tree)를 보여주거나 디버거를 통한 분석 방법이 이에 속한다.

이번에 소개할 Code Analysis는 정적인 분석 방법에 해당하는 것으로 코드를 실행함으로써코드에 내제되어 있는 문제점을 알려준다. 이와 반대로 동적인 분석 도구에는 프로파일러(Profiler)가 주로 사용된다. 앞에서 말했듯이, 정적인 분석 도구는 코드를 실행하지 않기 때문에 코드의 성능에 대한 구체적인 자료를 제시할 수 없다. 대신 작성된 코드 자체에 대한 분석이 주요 기능이다.

Code Analysis는 기존에 FxCop이라는 이름으로 CLR 팀에서 공개해왔던 툴이 Visual Studio Team System(VSTS)에 통합된 버전이다. FxCop의 구체적인 기능은 관리되는 코드(Managed Code)가 Microsoft .NET Framework의 디자인 가이드라인을 따르고 있는지 검사하는 코드 분석 툴이며, http://www.gotdotnet.com/team/fxcop에서 다운로드 받을 수 있다. 보다 구체적으로 설명하면, FxCop은 작성된 코드가 COM interop를 제대로 사용하고 있는지, 또는 고성능 코드를 작성하기 위한 규칙들을 지키고 있는지와 같은 200개가 넘는 규칙들에 대해서 코드를 검사한다.

FxCop이 VSTS 이전부터 많이 사용되어 왔지만(개발자에게 공개되는 도구), VSTS에 와서 Code Analysis라는 이름으로 용어가 변경되었기 때문에 MSDN 도움말에서 FxCop에 대한 도움말 찾기 위해서는 Code Analysis라는 이름으로 검색을 해야 적절한 도움말을 확인할 수 있다. Code Analysis와 FxCop과의 관계에 대해서는, 거의 대부분의 기능이 무료로 배포되는 FxCop 버전과 동일하지만, CLR 팀에 의하면 무료 버전에서 지원하지 않는 기능을 Code Analysis에서 지원한다. 하지만 두 기능의 차이가 분명하지 않기 때문에 어느 버전을 사용하더라도 대부분의 오류를 찾아내는 데에는 전혀 문제가 없을 것이다.

그럼 간단한 예제를 통해서 Code Analysis의 기능을 살펴보도록 하자.

앞으로 사용할 예제 소스 코드 는 다음과 같다.

#region Using directives
using System;
#endregion

namespace testCode
{

    public class demo : Exception
    {

        public static void Initialize(int size) { }
        protected static readonly int _item;
        public static int item { get { return _item; } }
    }
}

Code Analysis 활성화 하기
프로젝트를 생성하면 기본적으로 Code Analysis 기능이 비활성화되어 있다(이 기능은 자동 실행 기능에 대한 활성화 유무이지 사용 가능성에 관한 기능은 아니다). 만약 Code Analysis 기능을 활성화하면, Visual Studio는 프로젝트를 빌드할 때마다 매번 Code Analysis를 수행할 것이다. 물론 Code Analysis 기능을 활성화하지 않더라도 Run Code Analysis 메뉴를 선택하여 수동으로 Code Analysis를 실행할 수 있다. 만약 프로젝트를 빌드할 때마다 Code Analysis를 수행하고 싶다면, 설명한 것처럼 속성 창에서 Code Analysis 기능을 활성화할 수 있다. 이 때, 프로젝트의 종류에 따라서 Code Analysis를 설정하는 위치가 다르기 때문에 약간의 주의를 필요하다. 일반 관리되는 코드인 경우에는 다음 그림과 같이 프로젝트의 속성 창을 띄운 후 Code Analysis 탭을 선택하여 Enable Code Analysis 체크 상자를 선택하면 된다.


반면에 ASP.NET 응용 프로그램의 경우에는 Website 창을 띄운 후 Code Analysis Configuration 탭을 선택하여 Enable Code Analysis 체크 상자를 선택한다. 아마도 프로젝트를 생성하여 코드를 작성한 후 처음으로 Code Analysis를 실행하면 상당히 많은 경고가 발생할 것이다. 발생한 경고들을 지금 바로 해결하지 않아도 된다면, 아마도 빌드할 때마다 Code Analysis를 실행하는 개발자는 많지 않을 것이다. 뿐만 아니라 프로젝트의 크기가 커질수록 Code Analysis를 실행하는데 많은 시간이 걸리기 때문에 잦은 빌드를 수행하는 개발팀에서는 오히려 부담이 될 수도 있다. 하지만 일별 빌드(Daily build)를 수행하는 팀은 빌드가 끝난 후 자동으로 Code Analysis를 실행함으로써 자동으로 코드를 검증할 수 있다. 자신이 속한 팀의 빌드 정책에 맞게 옵션을 설정하도록 한다.

Enable Code Analysis 체크 상자를 선택하는 것과 관련해서 주의해야 할 점은 외부로 배포될 릴리즈 빌드에는 이 기능을 활성화해서는 안된다는 점이다. 이 기능을 활성화하면 위의 그림에서 확인할 수 있는 바와 같이 CODE_ANALYSIS 상수를 정의하게 되는데, CODE_ANALYSIS 상수가 정의되면 SuppressMessage 애트리뷰트가 바이너리에 추가되어 자칫 성능에 영향을 미칠 수 있기 때문이다.

Code Analysis 실행하기
우선 앞서 소개한 ManagedDemo 솔루션을 MSDN 도움말에서 다운로드를 받거나 새로운 C# 프로젝트를 생성하여 ManagedDemo 코드를 작성한다. 새로운 프로젝트가 생성되었다면 속성 창을 열고 Enable Code Analysis (defines CODE_ANALYSIS constant) 체크 상자를 선택하고 속성을 저장한다. Code Analysis가 활성화되어 있기 때문에 빌드를 수행하면 다음과 같이 Error List 창에 빌드 오류가 보고될 것이다.


만약 ManagedDemo와 동일한 코드를 작성했다면, 총 15개의 오류를 확인할 수 있을 것이다. Error List 창의 상단에 보면, Error의 수와 Warning의 수, 그리고 Message의 수를 확인할 수 있으며, 버튼을 클릭하여 특정 타입의 오류가 표시되거나 표시되지 않도록 할 수 있다. 기본적으로 Error List 창은 모든 타입의 오류를 표시한다.

오류 분석하기
Code Analysis를 실행하여 발생한 오류는 고유한 오류 번호를 갖는다. 예를 들면, 위의 그림에서 6번 경고는 CA1709라는 오류 번호를 갖는다. Description 칼럼은 각각의 경고가 발생한 이유에 대해서 설명하고, File과 Line은 각각 소스 파일과 줄 번호를 표시한다. 많은 경우에 Description에 설명된 내용만으로도 경고를 어떻게 제거할 것인지를 알 수 있지만, 만약 더 많은 정보가 필요하다면 경고를 선택한 후 F1을 눌러 오류 번호에 대한 자세한 도움말을 살펴볼 수 있다. 도움말을 처음 이용하는 경우에는 다음과 같이 도움말을 선택할 수 있는 창이 뜨는데, 일반적으로 온라인 도움말을 이용하는 것보다는 컴퓨터에 설치된 도움말이 더 빠르기 때문에 다음 그림에서와 같이 Use Local Help as primary source를 선택한 후, OK 버튼을 클릭하여, 도움말을 실행하도록 한다.


그리고 다음 그림과 같이 CA1709 경고에 대한 자세한 내용을 확인할 수 있다. 앞서 소개한 그림에는 나타나지 않았지만, How to Fix Violations라는 항목을 통해서 발생한 경고를 해결할 수 있는 방법을 자세하고 소개하고 있다. 이 경우에는 "Change the name so that it is cased correctly."와 같이 해결책을 제시하고 있다.


도움말을 사용하거나 Description을 통해서 경고에 대한 원인을 파악하고 해결책이 떠올랐다면, 경고가 발생한 코드로 이동하여 경고를 제거할 수 있다. 하지만 만약 특정한 경고의 경우 굳이 코드를 변경하여 제거할 필요가 없다면, 다음과 같이 경고를 선택한 후, 마우스 오른쪽 버튼을 눌러 Suppress Message(s) 메뉴를 선택할 수 있다.


6번째 경고에서 Suppress Message를 선택하면, 다음과 같은 코드가 demo 클래스 위에 추가된다.


[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
    public class demo : Exception
    {

        public static void Initialize(int size) { }
        protected static readonly int _item;
        public static int item { get { return _item; } }
    }

그리고 다음 그림과 같이 6번 줄은 경고가 삭제되었다는 의미로 줄이 그어진다.


하지만 앞서 설명한 것처럼 이와 같이 SuppressMessage 애트리뷰트를 사용하면 성능에 영향을 미칠 수 있기 때문에 가능하다면, 적절한 조치를 취해서 경고를 없애는 것이 바람직하다.

지면상, 각각의 모든 오류를 제거하는 방법에 대해서 소개하지는 않았지만(대부분의 해결 방법은 도움말을 통해서 얻을 수 있다), Code Analysis를 실행해서 얻은 대부분의 경고는 개발자가 주의를 한다면 사전에 예방이 가능하다. 물론 익숙해 지기 위해서는 어느 정도의 시간이 필요할 것이다. 특히 이름 규약의 경우에는 이름 규약을 지키기 위해서 지금까지의 시도되어왔던 많은 방법들 중 가장 강력한 기능이다. Code Analysis를 사용하여 나쁜 코드의 흔적을 완벽하게 제거해 보자~!

필자 서우석님은 Microsoft MVP이며, 현재 카이스트 대학원 재학 중이며, C관련 프로그래밍에 능통하다.