티스토리 뷰

많은 개발자들이 쓰고 있는 IDE인 Visual Studio.
Visual Studio에는 디버깅 모드와 릴리즈 모드가 있죠, 릴리즈 모드는 프로그램을 배포하기 위해 컴파일 하는 모드로, 디버그모드로 컴파일시 들어가는 디버깅에 필요한 자질구리한 정보를 뺀 알짜 프로그램만 쏙~ 뽑아내는것 입니다.

하지만 단지 이것만 생각하기엔 디버깅 모드와 릴리즈 모드는 이상한 다른점이 있어요. (이상하고 정말 이상해요)

그 이상하고 황당한 다른점을 소개해드리고자 합니다.

첫번째, 릴리즈모드는 초기화를 해주지 않는다.
어느정도 경험이 있는 개발자라면 다 알고 있는 사실입니다. 하지만.. 제가 겪은건 좀 황당해요.

2년전 학교에서 텀프로젝트를 하면서 발견했던 현상입니다.
이는 Visual Studio의 버그인지는,, 확실히 모르겠습니다만 Visual Studio .NET 2003에서 발생하는건데요,

C/C++의 기본서에 모두 써 있는 내용이 있습니다. "전역변수는 0으로 초기화된다". 특별한 명시를 해주지 않아도 전역으로 선언한 변수들은 초기값이 0으로 된다는 말입니다. 굳게 믿고 전역변수들은 컴파일러가 알아서 초기화를 잘 시켜줄거라 생각을 했죠.

하지만 그 전역변수에서 문제가 발생했었습니다. 초기화를 따로 시키지 않고 사용을 했었는데 Release모드로 컴파일하니 값이 처음엔 0으로 잘 나오다가 값자기 값이 바뀌는겁니다 -_-; 정말 황당했어요, 처음부터 값이 제대로 나오지 않았다면 초기화에 문제가 있구나~ 라고 생각할 수 있겠는데 값이 갑자기 바뀌어 버리는겁니다. 당시 프로젝트 과제를 제출할때는 해결을 하지 못해서 Debug모드로 제출을 했었지만, 나중에 "디버그모드에서 잘 돌아가다가 릴리즈모드에서 에러가나는것은 초기화문제 때문일 가능성이 크다" 라는 글을 보고서야 초기화구문을 넣어주니 제대로 동작하는것을 확인할 수 있었습니다.


두번째, 릴리즈모드는 같은 문자열 상수라도 서로다른 공간에 할당한다.

char *a = "ABCDE";
char *b = "ABCDE";
if( a == b )  printf("Good!\n");
else           printf("Bad!\n");


이 코드의 실행결과는 어떨까요?

a, b모두 같은 문자열이므로 Good! 이출력됩니다. 라고 말하는 분은 없을꺼라 생각합니다. 쌍따옴표로 묶인 문자열은 C/C++에서는 문자열상수로써 메모리공간에 할당이 되고, 그 주소값이 a와 b에 들어가므로 다른곳에 값이 할당될때는 틀릴수도 있습니다.

컴파일러가 "같은 문자열 상수"일경우엔 최적화 과정을 통해서 a가 가르키는 "ABCDE"와 b가 가르키는 "ABCDE"를 동일한 메모리 공간상에 할당을 하고 그 주소를 반환해주기 때문에 Good!이 출력됩니다. 라고 대답하는 분은 있으실꺼라 생각됩니다. 물론 저도 그렇게 생각하고 있었고요. Debug모드에서는 위 설명대로 작동이 됩니다. 문자열상수의 값이 같으면 그 주소값도 같게 되요.

하지만, Release모드에서는 두 문자들을 서로 다른 메모리공간에 할당을 합니다. a와 b의 값이 다르게 되요. VS 6.0이나 .NET 2005이상은 어떨지 모르겠습니다만.. 회사에서 쓰는 Visual Studio.NET 2003 에서는 이런 현상이 일어나네요..

혹, 컴파일옵션을 바꾸면 어떨까.. 하는 생각에 Debug모드와 Release모드 사이에 옵션중 다른점을 모두 같게 고치고 했는데도 Bad!가 나옵니다. _no

/*
    첫번째 덕분에 전역변수도 초기화해서 사용하는 버릇이 생겼습니다. 객체지향 개발방법론으로 코딩할때는 전역변수를 쓸일이 없지만요;

    두번째 같운경우는 좀 아쉽습니다. 같은 문자열상수면 같은 공간에 할당되었으면 하는데 혹시 Release모드에서도 같은문자열상수는 같은공간에 할당되도록 설정하는 방법이 있는지 아시는분은 덧글 남겨주세요 :D
*/

댓글
  • 프로필사진 selfi 헐.. 디버그 모드에선 값이 Good이 출력될 수가 있군요;
    신기하당;; 컴파일러가 pointer의 주소값으로 바꿀 수 없는 상수 이미지에 들어가는
    값을 다 비교를 해본다는 거자나요. ㅡㅡ.. 아하하;;


    릴리즈 모드에선 쓰레드 코드를 작성했을때
    a 값을 공유하는 두 코드에서
    한쪽에서 a를 바꾸어도 레지스터 값만 바뀌고 메인메모리에 있는 값은 바뀌지 않아서
    다른 코드가 a작업을 할때 바뀌지 않은 값을 가지고 작업을 해서 고생했...던 경험은 누구나
    있겠지요;
    2007.09.20 01:02
  • 프로필사진 Favicon of http://mastojun.net BlogIcon Mastojun 재미있는것은 gcc는 항상 Good을 출력한다는거예요, 그래서 VS Release모드도 (당연히-_-?) Good이 출력될꺼라고 믿고 있었죠...;

    쓰레드 관련 이야기는..
    운영체제 수업시간에 메모리계층구조 공부할때 들었던 기억이 나요ㅋ
    직접 경험해본적은 없지만요 (....;;)
    2007.09.20 10:25
댓글쓰기 폼