티스토리 뷰

[원본 - 2013년 이글루스]


대게의 경우 변수 이름을 아무 생각없이 막 쓰지 않는 이상 스코프에 의한 런타임 오류는 경험하기 힘들다

가장 많이 찾아볼 수 있는 스코프 오류는 for문을 사용할 때 이다

이 역시 컴파일러의 해석 차이에 의해서 생기는 스코프 오류로

이 이슈가 가장 많이 문제 시 되었던 시기는 VS 6.0 에서 최신 버전으로 넘어가면서 이다

int main()
{
    for( int i = 0 ; i < 10 ; i++ ) {
        // Do Something
    }

    printf("%d", i );
    return 0;
}

i 의 스코프는 어디까지 유지 되는가?

VS 6.0을 쓰던 사람은 for문 이후 main문 끝까지 유지된다고 할 것이고

그 이외의 컴파일러를 쓰는 사람은 for문 내에서만 유효하다고 할 것이다

이 정도의 이슈가 그나마 현업에서 가장 자주 만날 수 있는 스코프 오류의 '주' 였다



오늘 이야기하고자 하는 내용도 for문과 관련이 있다

어떻게 보면 너무 당연한 내용이지만... 아차 하고 넘어갈 수 있는 부분이다

오늘 문제가 될 코드는 아래와 같다

int main()
{
    int tmp = 0;
    for( int i = 0, tmp = 0; i < 10 ; i++, tmp++ ) {
        // Do Something
    }

    printf("%d\n", tmp );
    return 0;
}

위의 코드의 결과는 무엇일까?

C로 할경우는 확실히 에러일테고, C++의 기준으로 생각해 보자

일단 본인 주변에서는 의외로 위의 문제에 한번에 정답을 말하는 이가 적었다


먼저 정답을 말하자면

VS 6.0에서는 에러 gcc와 최신버전의 VS ( 2008과 2010 만 일단 확인 ) 컴파일러의 경우 0 을 출력한다


10 이라고 생각한 사람들은 코드를 잘 살펴보아라. 콤마(,) 때문에 착각할 수도 있는 문제다


for문을 사용할 때, 다중 초기화 및 다중 가감산 연산을 취할 경우 우리는 콤마(,) 를 사용하여 구분한다


위의 경우도 본래의 의도는

i를 생성 0으로 초기화 한 후, 이미 선언된 tmp 를 0으로 초기화하라고 생각하고 작성하기 쉽다


물론 i와 tmp가 for문 이전에 선언되어 있었다면 의도한 대로 될 것이다


하지만 선언문 뒤에 콤마가 붙어 버렸기 때문에 위의 코드는 다음과 같이 해석 된다

int main()
{
    int tmp = 0;

    {
        int i, tmp;
        for( i = 0, tmp = 0; i < 10 ; i++, tmp++ ) {
            // Do Something
        }
    }

    printf("%d\n", tmp );
    return 0;
}

즉, for문 스코프 내에 tmp 변수를 한번 더 선언한게 되기 때문에

for문 내에서 tmp 변수를 아무리 바꿔봤자 for문 내의 로컬 tmp 변수를 바꾼 것일 뿐

그 밖에 있는 원래 tmp에는 아무런 영향이 없다는 것이다


디버그 모드로 돌려보아도

VS의 Auto나 Watch 탭에서는 for문의 tmp가 잡혀서 값이 정상적으로 들어간 것 처럼 보이지만...

실제 Local 탭에는 tmp 변수가 바뀌지 않음을 확인할 수 있다


VS 6.0의 경우 for문 안과 밖이 같은 스코프로 취급하기 때문에 재정의 오류가 발생한다


위의 코드가 좀 억지스러운 상황을 만들기는 했지만, 실제로 현업에서 어쩌다 한번씩 발견되는 실수다

코드의 모호성을 줄이고, 해당 스코프 오류를 줄이기 위해서

가능한 for문에 사용 할 변수의 경우 for문 밖에서 미리 선언하고 사용하는 것이 안전하다

댓글
최근에 올라온 글
Total
Today
Yesterday
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31