많은 프로그램 언어에서, 변수는 사용되기 전에 선언되어야 한다.

선언이란, "난 이것을 사용하겠어!"라고 선언하는 과정이다. 왜 선언을 해야 할까?

변수를 선언하는 이유는 변수를 어떤 방법으로 사용할 것인지 컴퓨터에게 알려주는 과정이기 때문이다. 컴퓨터의 메모리 공간에 기록되어 있는 숫자들은 각각 어떤 의미를 갖고 있는데, 그게 어떤 의미인지 알려주지 않으면 컴퓨터는 그 숫자를 읽어도 처리할 수가 없다. 그 의미를 알려주는 것이 선언이다. 이게 변수인지 프로그램인지, 이게 2바이트 기준인지 4바이트 기준인지, 이게 한번 쓰고 버릴 건지 계속 사용할 건지, 이걸 혼자 쓸건지 같이 쓸건지 등등을 알려줘야 한다.

만약, 변수가 1가지 종류(type)만 있었다면 선언이 필요 없을지도 모른다. 가령, 2바이트 부호있는 정수형 변수만 사용된다면, 선언을 하지 않아도 괜찮을 수 있다. 물론 그런 경우에도 변수의 다른 특징들을 컴퓨터에게 알려주려면 선언을 해야 할 수도 있다.

물론 선언하지 않아도 되는 프로그램 언어도 있다. 그런 경우에는, 변수가 처음 사용되는 시점에서 그 변수에 대입되는 값이 뭔지 따져서 변수의 종류와 처리방법을 결정하는 언어도 있다. 편리하기는 하지만 그런 언어는 쓰다보면 헷갈리는 부분도 있어서, 개인적으로는 별로 좋아하지 않는다. (쓰라면 쓰겠지만. -_-;)

변수를 사용하기 전에 선언하는 이유는 컴파일러의 처리 방식때문이다. 컴파일러는 앞에서부터 읽어가면서 기계어로 번역을 하는데, 변수가 어떻게 사용하는건지 모르고서 쓰라고 하면 짜증내면서 컴파일을 관둔다. [각주:1] 물론, 뒤에 선언이 되어 있더라도 컴파일러의 처리 방식에 따라서 프로그램을 두번 읽어서 번역할 수 있는 것들도 있다. 이건 편하긴 한데, 두번 읽어야 하니까 당연히 컴파일 시간이 거의 두배 걸린다.


  1. 이건 사람의 언어를 읽을 때도 대명사가 나왔을 때 앞에 나온 어떤 명사를 지칭하는 것인지 알 수 없으면 글이 도저히 읽혀지지 않는 것과 같다. [본문으로]
by snowall 2010. 10. 8. 09:28
  • kabbala 2010.10.08 11:32 신고 ADDR EDIT/DEL REPLY

    선언할 때 1번 + 처음 나왔을 때 1번 = 처음 나왔을 때 2번

    같은 거 아닌가요?

    • snowall 2010.10.08 12:33 신고 EDIT/DEL

      프로그램 전체를 두번 읽는 것과 변수만 두번 구경하는건 다르죠

  • goldenbug 2010.10.08 12:59 ADDR EDIT/DEL REPLY

    원한다면 그때그때 선언하면서도 충분히 사용하도록 컴파일러를 만들 수 있겠지만, 그게 프로그래밍에 더 어려움을 불러오기에 미리 선언하도록 만드는 것이라고 알고 있습니다만...^^

    • snowall 2010.10.08 13:18 신고 EDIT/DEL

      그때그때 선언해도 "사용하기 전"에 선언해야 합니다.
      모아놓든 따로놓든, 사용 전에 선언하는게 규칙이죠

    • goldenbug 2010.10.09 01:35 EDIT/DEL

      컴파일러를 만들기에 따라서 사용 이후 선언하게 만들 수도 있다는 이야기죠. 물론 뒤에 선언된 변수를 컴파일러가 조사해서 사용하기 전에 메모리할당을 하면서 변수를 선언하는 형식으로 만들어야 하겠죠.
      하지만 이렇게 하는 것은 잘 아시겠지만 프로그램 개발과 유지에 불리할 것이란 이야기입니다.

  • 2010.10.08 13:09 ADDR EDIT/DEL REPLY

    항상 이곳 글 재미있게 읽고 있습니다. 제가 아는 바와 조금 달라서..

    언급하신 내용은 대략 C 패밀리에 적용되는 이야기 같은데, 이쪽에서 선언을 하는 이유는 형을 알아내기 위해서가 아닙니다. 물론 각 변수의 형 정보는 필요하지만, 그렇다고 그것이 처음에 명시적으로 선언해주지 않으면 얻기가 불가능한 정보는 아닙니다. 말씀하신 대로 변수가 처음 사용되는 부분을 분석하면서 컴파일러가 충분히 추론할 수 있습니다. 오히려 C 패밀리는 포인터에다 정수를 더하거나 거꾸로 정수를 포인터처럼 써버려도 되고, 'a' 에다 1을 더하면 'b'가 되며, 심지어 int32_t 의 배열을 하나 만들고 int8_t 의 포인터로 가리킨 뒤 한 칸씩 이동하며 값을 읽어 보면 4 바이트씩 잘려서 읽어지죠. 형에 관한 한 상당히… 무개념합니다. (나쁜 의미로가 아니라, 말 그대로 아무런 개념적 강제나 강요가 없으므로)

    진짜 형에 엄격한 강형 (strongly typed) 언어로는 해스켈이 있는데, 해스켈에선 'a' + 1 같은 짓은 용납되지 않습니다. C 패밀리처럼 형이 연산자나 함수에 따라서 '알아서 바뀌는' 일은 결코 없고, 필요하면 "정수를 먹고 문자를 뱉는" 함수 등을 명시적으로 사용해주어야 하죠. 그런데 정작 해스켈에는 변수 선언 같은 과정이 전혀 없습니다. 컴파일러의 형 추론이 완벽하게 동작하고, 메모리도 알아서 잡히며, 같은 이름을 명시적 변환 없이 서로 다른 형으로 취급한 곳이 있으면 귀신같이 찾아내서 컴파일 오류를 던집니다.

    더 극단적인 예로는 C의 전신인 B가 있습니다. snowall 님은 "만약, 변수가 1가지 종류(type)만 있었다면 선언이 필요 없을지도 모른다."라고 하셨는데, 실제로 B에는 형이 하나뿐입니다. 워드. 예를 들어 8 비트 아키텍처에서라면 8 비트짜리 자료형 하나밖에 없었던 것입니다. 그런데 B에서도 변수는 선언부터 해야 쓸 수 있었습니다.

    그렇다면 왜 "먼저 변수 선언부터"를 요구하는가? 제가 알기론, 기원을 찾자면 함수 호출 스택 관리를 위해서입니다. 아시다시피 함수가 하나 호출될 때마다 접근 가능한 지역 변수 등이 싹 달라집니다. 그래서 함수의 호출 과정이란, 먼저 함수 호출 이전의 상태를 따로 저장해둔 뒤, 새로이 호출된 함수가 활동할 공간을 마련하고, 거기서 함수를 실행하고, 다시 이전 상태를 복원하는 것으로 이루어집니다. 즉 함수를 호출하려면 새로운 공간을 잡아주어야 하는데, 이때 이 공간은 도대체 뭣으로 줘야 하는가? 집채만한 강의실이 필요한가 아니면 네 평짜리 화장실이 필요한가? 이것을 알아내는 가장 간단한 방법은 "나라는 함수는 이러이러한 공간을 요하며, 이러이러한 변수를 쓸 것이다."를 모든 함수 첫머리의 첫머리에 써주는 것이겠죠. 많은 초창기 언어에서 함수 개념이 이런 식으로 구현되었고, 그것이 C에 그대로 계승된 것입니다.

    • snowall 2010.10.08 13:20 신고 EDIT/DEL

      해스켈은 배우고 싶은 생각만 하고 아직 손도 못 대본 언어라서...
      신기하네요 -_-

      변수 선언과 함수 선언은 좀 다른과정인걸로 알고 있는데요...

    • 2010.10.08 13:40 EDIT/DEL

      함수 선언이 아니라, 변수를 선언할 때 함수의 첫 부분에 선언하는 이유가 저렇다는 뜻입니다.

    • snowall 2010.10.08 13:51 신고 EDIT/DEL

      많은 언어에서 변수 선언은 함수 첫머리에 와야만 하는건 아니고, 사용 전에만 있으면 됩니다.
      아무튼 메모리 공간 관리를 위해서 필요하다는 건 알겠습니다.

      선언이 변수의 종류와 사용방법을 알려주는 것 외에 다른 기능이 있었다는건 처음 알았네요.

  • 구차니 2010.10.09 23:19 신고 ADDR EDIT/DEL REPLY

    악! 이거슨.. 저로 부터 시작된 글인가요? ㅋ
    아무튼 프로그래밍의 이러한 내부적인 원리를 파고들수록 정말 내가 아는게 하나도 없구나 라는 생각만 들어서 자괴감에 빠지곤 해요 ㅠ.ㅠ

    • snowall 2010.10.09 23:23 신고 EDIT/DEL

      아...뭐 저도 아는건 없어요...-_-
      그리고 구차니님때문에 시작된건 아니니까 걱정 마셔요 ㅋㅋ

    • 꽃마조 2010.10.13 21:15 신고 EDIT/DEL

      실은 저로부터 ㅋㅋ

  • kabbala 2010.10.10 14:13 신고 ADDR EDIT/DEL REPLY

    그럼 처음에 변수를 선언하지 않는 언어(컴파일러)의 경우 변수를 사용할 때마다 새롭게 선언하는 것으로 이해하고 계신 건가요?

    • snowall 2010.10.10 19:44 신고 EDIT/DEL

      그럴리가요
      그건 처음 사용할때 선언이 함께 이뤄지고, 그때부터 그 변수를 쓰는 걸로 알고 있는데요

  • blacksoul5 2015.12.09 08:48 ADDR EDIT/DEL REPLY

    변수 선언을 하고 나면.. 어차피 실행이 되어서 보여지는건 숫자나 글씨뿐인데..
    그냥 타이핑으로 표현하는 것과 변수선언과는 뭐가 다른가요..
    보여지는 게 같다면,, 굳이 변수 선언을 왜 해야 하는지 잘 모르겠습니다..
    음.. 프로그램이 그렇게 하라니까 그렇게 해,, 이런건가싶기도 하고,,

    • snowall 2015.12.10 09:50 신고 EDIT/DEL

      변수선언은 변수가 어떤 종류인지 알려주기 위해서 합니다. 이게 없으면 컴파일이 느려지거나 실행이 느려지거나 아예 안되거나 합니다. 어쨌든 변수가 어떤 종류인지 모르면 그 안에 저장된 정보를 해석할 수가 없거든요.