C 프로그래밍: 현대적 접근_01.C 입문

alegruz@khu.ac.kr
2018-03-05
조회수 13210

이 글은 K.N.King 의 C Programming: A Modern Approach의 번역임을 알려드립니다.

모든 저작권은 저자인 K.N.King과 출판사인 W.W.Norton에 있습니다.


1. C 입문

C란 무엇인가? 간단하게 답하자면 1970년대 초 벨 랩에서 개발된 광범위하게 사용되는 프로그래밍 언어라고 할 수 있다. 하지만 이런 대답으로는 C가 정말로 무엇인지 제대로 된 맛을 볼 수 없다. C에 대해 좀 더 구체적으로 들어가기 전에, C가 어디서 왔고, 뭘 하려고 만들어졌으며, 지난 수년간 어떻게 바뀌었는지에 대해 한 번 1,1번에서 알아보도록 하자. 또한 C의 장점과 단점, 그리고 C를 어떻게 하면 최대한의 장점을 뽑아낼 수 있는지에 대해서도 1.2에서 얘기해보도록 하자.


1.1 C의 역사

C의 역사에 대해 간단하게 알아보자. C가 어디서 왔고, 표준화된 언어가 어떻게 되었고, 최근 언어들엔 어떤 영향을 미치는지에 대해서 얘기해보도록 한다.


유래

C는 UNIX 운영체제의 산물이며, 벨랩에서 일하던 켄 톰슨, 데니스 리치 등이 만들었다. 톰슨은 DEC PDP-7이라는 컴퓨터에서 돌아가는 UNIX 운영체제의 원본을 거의 혼자서 만든 인물인데, 이 컴퓨터는 오로지 8000개의 단어 밖에 주기억장치에 저장할 수 있었던 작은 컴퓨터였다. 애초에 이 때는 1969년이었다.

당시 다른 유명 운영체제처럼, UNIX 또한 어셈블리어로 제작되었다. 어셈블리어로 제작된 언어들은 주로 디버깅을 하거나 성능을 업그레이드할 때 매우 힘들다는 특징을 갖고 있었다. UNIX도 다를 바 없었다. 이러한 단점 때문에 톰슨은 UNIX 개발을 지속하기 위해선 어셈블리어보다는 좀 더 고급 언어가 필요하다고 생각했다. 그래서 그가 제작한 언어가 바로 B 언어이다. B 언어는 60년대 중반에 제작되었던 BCPL이라는 시스템 프로그래밍 언어를 기반으로 만들어졌다. BCPL의 경우 가장 최초이며 가장 영향력 있었던 언어 중 하나인 Algol 60에서 영향을 받은 언어이다.

후에 리치가 UNIX 프로젝트에 참여하게 되었고, 톰슨이 제작한 B를 사용하여 프로그래밍을 했다. 1970년이 되자, 벨랩은 UNIX 프로젝트에 PDP-11라는 컴퓨터를 지원했다. B가 이 컴퓨터에서도 돌아갈 수 있게 되자, 톰슨은 UNIX의 일부를 어셈블리어가 아닌 B 언어로 프로그래밍을 했다. 1971년이 되자 그들은 B 언어가 PDP-11에는 잘 맞지 않다는 것을 발견했다. 그래서 리치는 B의 좀 더 발전된 언어를 제작했고, 이것을 New B라는 의미로, NB라고 이름지었다. 그러다가 후에 B에서 더더욱 발전을 해서 B와는 많이 달라진 형태가 되었는데, 이 때 리치는 이것을 C라고 이름지었다. 이 언어는 1973년이 되자 UNIX 전체를 C로 프로그래밍할 수 있을만큼 C는 발전하고 안정화되었다. C로의 전환은 많은 장점을 낳았는데, 그 중 제일 중요한 것이 바로 확장성이다. 벨랩에선 C가 다른 컴퓨터에서도 돌아갈 수 있게 다양한 C 컴파일러를 제작하고 나서야 UNIX를 다양한 기기에서 사용할 수 있었다.


표준화

C는 70년대 내내 발전을 해왔다. 특히 77년과 79년 사이 때 급격하게 발전을 했는데, 이 시기가 바로 C에 대한 첫번째 책이 출판된 시기이다. 바로 브라이언 커니핸과 데니스 리치가 78년에 출판한 The C Programming Language이다. 이것은 순식간에 C 프로그래머들의 바이블이 되었다. 당시 C에 대한 표준이 정해지지 않은 시기에 "K&R", 혹은 일부 C 언어 광신도들에게 "하얀 책"으로 불리우던 이 C 언어의 바이블은 순식간에 C 언어의 표준으로 자리를 잡았다.

70년대엔 사실 상대적으로 C 언어 프로그래머들이 적었다. 당연히 대부분은 UNIX 운영체제를 사용하던 이들이었다. 허나 80년대가 되자 단순히 UNIX라는 좁은 시장에서 벗어나 엄청나게 넓은 범위까지 퍼져나갔다. C 컴파일러는 순식간에 어느 운영체제든, 어느 컴퓨터이든 지원하기 시작했다. 특히 C 언어는 제일 발전 속도가 빨랐던 IBM의 PC 플랫폼 분야에서 엄청난 권위를 갖게 되었다.

엄청난 인기에는 시련이 따르는 법, C 컴파일러를 짜던 대부분의 프로그램은 K&R에 의존하던 이들이엇으나, K&R 책에는 단점이 있었다. 바로 언어가 제공하는 일부 기능에 대한 설명이 구체적이지 않았던 것이다. 그렇기 때문에 C 컴파일러마다 이 분야에 대한 해석에 제멋대로였다. 또한 K&R은 C가 갖고 있던 특징과 UNIX가 갖고 있던 특징에 대해 정확하게 구분하지 못했다. 게다가 C 언어는 책의 출판 이후에도 새로운 특징은 추가되고, 기존의 특징들은 삭제되면서 계속해서 발전하고 있었다. 이 모든 것은 불에 기름을 붓는 격이 되었다. 결국, C 언어에 대한 명확하고 구체적이며, 변경될 때마다 이에 대한 설명을 명시해놓는 설명서가 필요해진 것이다. 이러한 표준 설명서가 없으니 C 언어에는 여러 가지 방언이 생겨서 C 언어가 갖고 있었던 확장성이라는 장점을 무색하게 만들었다.

1983년, 미국규격협회(ANSI)를 중심으로 C의 표준화를 위한 작업이 미국에서 시작되었다. 수차례의 수정을 거쳐 88년에 마침대 표준은 완성되었고, 다음해 12월 ANSI 규격 X3.159-1989로서 미국규격협회의 승인을 받으면서 공식화되었다. 90년에 가서는 국제표준화기구(ISO)에서 국제 규격 ISO/IEC 9899:1990로서 승인을 받았다. 이 당시 표준화된 C 언어를 통상적으로 C89, 혹은 C90라고 부른다. 이는 K&R C라고 불리던 원조 C 언어와는 차별하기 위함이었다. 부록 (다)를 통해 C89와 K&R C의 대표적인 차이점을 확인할 수 있다.

1995년 당시 C 언어는 수정 제1조라는 이름으로 몇 개의 변화를 맞이한다. 좀 더 대대적인 변화는 99년에 이뤄졌던 ISO/IEC 9899:1999이라는 새로운 규격의 출판에 의해 이뤄졌다. 이 때 나온 C 언어를 보통 C99라고 부른다. 한 때 C89를 부르던 용어인 "ANSI C", "ANSI/ISO C"나 "ISO C"는 이제 표준이 두 가지가 되어서 명칭이 모호해졌다.

C99가 아직은 전 세계적으로 영향력이 있지 않고, 또한 옛날 C 버전으로 짜인 백만, 혹은 천만 줄이나 되는 코드들을 유지할 필요성 때문에 C99에 새로 추가된 특징을 언급할 땐 따로 [C99] 이라고 언급을 하도록 하겠다. 이러한 특징들을 반영하지 못하는 컴파일러는 "C99-호환"이 아니다. 역사가 우리에게 알려준 것이 있다면, 모든 C 컴파일러들이 C99-호환이 되려면 적어도 수년은 기다려야 할 것이다. (2008년 기준) 만약 C99-호환 컴파일러를 사용하거나, 그러한 시대가 온다면, 부록 (나)에서 C99와 C89의 대표적인 차이점들을 확인할 수 있다.


C 기반 언어들

C는 현대에 제작된 다양한 프로그래밍 언어들에 영향을 주었으며, 일부는 아예 C에 막대한 영향을 받았다. 다음 언어들이 제일 대표적인 C언어에 영향을 받았으면서 제일 많이 사용되는 언어들이다.

  1. C++은 C의 모든 특징을 갖고 있으나, 클래스와 다른 특징들이 추가되어 객체 지향 프로그래밍이 가능하다.
  2. Java는 C++에 기반하고 있는데, 그렇기에 C의 여러 특징을 공유하고 있다.
  3. C#은 비교적 최근 언어로, C++과 Java에 영향을 받아 만들어졌다.
  4. Perl은 본디 비교적 쉬운 프로그래밍 언어였다. 시간이 지나자 C의 많은 특징들을 공유하기 시작했다.

이러한 새로운 언어들의 인기를 고려해본다면, 굳이 C를 배워야 하냐는 질문을 가질 수도 있을 것이다. 필자는 굳이 배워야 한다고 생각한다. 우선 C를 배우게 되면 위의 언어들과 같이 C를 기반으로 하는 언어들을 공부할 때 엄청난 통찰력을 갖고 공부할 수 있다. 이러한 언어들을 처음으로 배우는 프로그래머들은 대부분 C에서 영향을 받은 특징들을 제대로 습득하지 못한다. 두번째 이유는 생각보다 주변에 C 언어로 작성된 프로그램이 많기 때문이다.  당장 이러한 코드를 유지보수해야하는 일이 생길 수도 있다. 마지막으론 C가 아직(2008년 기준)은 새로운 소프트웨어를 개발하는데 사용되기 때문이고, 이러한 소프트웨어는 주로 메모리나 연산 능력이 한정되어있거나 C가 갖는 단순함이 필요하다.

만약 최근에 나온 C 기반의 언어를 사용해본 적이 없다면, 독자는 이 책을 통해 위의 언어들을 준비하기 위한 최고의 시작을 하고 있는 것이다. 이 책은 데이터 추상화, 정보 은폐 등 객체 지향 프로그래밍에 중요한 역할을 하는 많은 분야들을 강조하고 있다. C++은 이러한 C의 특징을 모두 갖고 있으므로, 이 책을 통해 사실상 C++을 공부하는 것과 다름 없는 것이다. C++ 뿐만 아니라 다른 C 기반 언어들에도 C 언어의 특징은 다수 발견된다.


1.2 C의 장점과 단점

다른 언어들이 그러하듯, C 언어 또한 장점과 단점이 있다. 장점과 단점을 이해하려면, 이 언어의 본 용도와 철학을 이해해야할 것이다. 본 용도라 함은 당연히 운영체제나 시스템 소프트웨어를 제작하는 것이다.

  • C는 저급 언어이다. 운영체제처럼 시스템을 제어하는 언어들은 바이트 단위와 메모리 주소값 등의 기계 수준의 개념까지 다룰 수 있어야한다. 이러한 특징은 사실 다른 많은 언어에서는 제공하지 않는다. 대부분 직접 제어하지 않고 밑에서 미리 짜여진 알고리즘에 의해 작동하기 때문이다. C는 또한 컴퓨터 자체에 내장된 지시들과 밀접하게 일치하는 연산들을 제공한다. 이를 통해 C 언어로 짠 프로그램들은 매우 빨라질 수 있다. 어플리케이션 프로그램은 인풋/아웃풋, 저장공간 관리 등 여러가지 서비스를 위해 그러한 연산들에 의존하기 때문에 운영체제는 느려서는 안된다.
  • C는 작은 언어이다. C는 다른 언어들에 비해 매우 한정된 특징들을 제공한다. K&R 2판에 경우 C 언어 전체의 참고 매뉴얼을 단 49페이지 만에 다룬다. 이렇듯 C 언어는 최대한 특징을 적게 갖고 있기 때문에 표준 함수들로 이뤄진 "라이브러리"에 매우 크게 의존한다. 여기서 함수라 함은 대부분의 다른 언어가 "절차", "서브루틴" 혹은 "메소드"라 부르는 것과 비슷한 것이다.
  • C는 관대한 언어이다. C는 당신이 스스로 무엇을 하고 있는지 알고 있다고 가정을 하고 있기 때문에, 다른 언어들에 비해 좀 더 큰 자유를 선사한다. 이는 곧 C 언어는 에러가 발생했을 때 구체적으로 무엇이 일어났는지에 대해 알려주지 않는다. 대부분의 다른 언어들은 이러한 구체적인 에러에 대한 설명을 제공한다.


장점

C의 장점을 읽어보면, C가 왜 이렇게 유명한지에 대해 이해할 수 있을 것이다.

  • 효율성. 효율성은 태초부터 C의 최고 강점 중 하나였다. C는 애초에 어셈블리어를 대체하기 위해 만들어졌기 때문에, C 언어로 짜인 프로그램들은 한정된 메모리가 내에서 최대한 빨라야 했다.
  • 확장성. C가 지향했던 제일 중요한 목표가 확장성은 아니었으나, 사람들이 사용해보니 확장성은 C 언어의 최대 강점 중 하나였다. 어떠한 프로그램이 일반 가정집 컴퓨터이든, 슈퍼컴퓨터이든 다 실행이 되어야 했다면, 대부분은 C 언어를 이용하여 프로그래밍 되었다. C 언어가 이렇게 확장성이 좋은 이유 중 하나는 C가 초창기에 UNIX와 관련이 있었기 때문이고, 후에 ANSI와 ISO에 의해 규격화 되었기에 여러 가지의 방언들로 나뉘지 않았기 때문이다. 또 다른 이유는 C 컴파일러들은 상대적으로 규모가 작았고, 프로그래밍하기도 쉬웠기 때문이다. 또한 C 언어 자체에 확장성을 제공하는 특징들이 있었다. 물론 그렇다고 하더라도 모든 프로그래머들이 다 확장이 가능한 프로그램을 짤 줄 알았던 것은 아니었다.
  • 힘. C의 다양한 자료형들과 연산자들은 C를 강력한 언어로 만들어 주었다. C에선 힘든 작업을 몇 개의 줄 만으로도 수행할 수 있다.
  • 유연성. C가 본래 시스템 프로그램을 위해 만들어졌지만, 여기를 위해서만 사용할 수 있는 것은 아니었다. C는 최근 임베디드 시스템이나 상업적인 데이터 처리 등 온갖 어플리케이션을 제작하는 데 사용된다. 또한 C는 스스로의 특징을 발현하는데 아주 적은 제한만을 둔다. 다른 언어에선 허용되지 않는 기능이 C 언어에서는 대부분 허용된다. 예를 들자면 C는 한 문자가 정수값이나 실수값에 추가될 수 있게 허용하고 있다. 이러한 유연함은 프로그래밍을 보다 쉽게 만들어준다. 물론 이러한 유연함은 몇 가지 버그를 발생시키기도 하지만.
  • 표준 라이브러리. 표준 라이브러리는 C의 최고 강점 중 하나다. 표준 라이브러리란  인풋/아웃풋, 문자열 처리, 메모리 할당 등 여러가지 유용한 함수들 수백가지를 갖고 있는 저장고이다.
  • UNIX와의 통합. C는 UNIX, 특히 UNIX의 변종인 Linux와 만났을 때 최고의 호흡을 보인다. 사실 몇 가지 UNIX의 기능들은 사용자가 C를 할 줄 안다는 전제하에 제공되기도 한다.


단점

  • C 언어로 짜인 프로그램들은 에러가 나기 쉬울 수 있다. C의 유연성에는 그 이면이 있다. 바로 에러가 나기 쉽다는 점이다. 다른 언어에서는 쉽게 잡힐 실수들이 C 컴파일러에선 잡히지 않을 수가 있다. 이러한 실행하기 전까진 에러가 있는 지 없는 지 모른다는 점에서 C 언어는 어셈블리어와 닮은 구석이 있다. 이러한 단점을 더더욱 힘들게 만드는 것이 있다. C 언어는 주의하지 않으면 실수를 할 수 있는 여러가지 낭떠러지들이 있다. 이후에 공부할 단원에선 실수로 추가한 세미콜론(;)이 어떻게 무한 루프를 생성해는지, 혹은 실수로 추가하지 않은 & 기호가 어떻게 프로그램을 고장내는지 알아보도록 하자.
  • C 언어로 짜인 프로그램들은 이해하기 어려울 수 있다. C가 상대적으론 작은 언어라고는 하지만, 다른 언어들에는 없는 기능들이 여럿 있고, 이러한 기능들이 특히 자주 잘못 이해하는 경우가 많다. 이러한 특징들에 의해서 원작자는 이해하기 쉽겠지만 타인들은 이해하기 어려울 수 있다. 또다른 문제는 C 언어의 간결함에 있다. C 언어는 현대에 비해 컴퓨터를 다루는 것이 제일 지루할 때 만들어졌기 때문에 C 언어는 의도적으로 프로그램을 만들거나 수정할 때 최대한 간결하게 해서 시간을 최대한 아끼려는 의도로 만들어 졌다. C의 유연성이 또한 단점이 될 수 있다. 너무 똑똑한 프로그래머들이 만든 프로그램들은 본인들 좋으라고 만든 것이기 때문에 남들이 보기엔 뭐라는 건지 못 알아 들을 확률이 높다.
  • C 언어로 짜인 프로그램들은 수정하기 어려울 수 있다. C로 짜여진 규모가 큰 프로그램들은 만약 애초에 유지보수를 할 생각으로 만든 것이 아니라면 수정하기 매우 어려울 수 있다. 최근에 나오는 언어들은 주로 클래스나 패키지라고 큰 프로그램을 여러 단위로 나누어 좀 더 관리하기 쉽게 만드는데, C는 그런 기능들이 없다.



일부러 C 언어 가독성 떨어뜨리기

C 언어를 열렬하게 사용하는 사람이라 하더라도, C 언어의 가독성이 떨어진다는 것은 인정할 것이다. 가독성 떨어지는 C 코드 짜기 국제대회(International Obfuscated C Code Contest. IOCCC)에선 실제로 매년 참가자들이 최대한 가독성 떨어지는 코드를 출품한다. 이 대회의 승자들의 코드들은 정말로 혼란스러운 코드들이 가득한데, 실제로 90년대에 "소규모프로그램상"을 수상한 코드는 다음과 같다.

v,i,j,k,l,s,a[99];

main()

{

for(scanf("%d",&s);*a-s;v=a[j*=v]-a[i],k=i<s,j+-(v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[l^v?(l^j)&1:2])&&++l||a[i]<s&&v&&v-i+j&&v+i-j))&&!(l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&++a[--i])

    ;

}

이 코드는 도론 오소블란스키와 바루흐 니센바움이 작성했다. 이 코드의 내용은 8퀸 문제에 대한 모든 해답을 프린트하는 코드인데, 8퀸 문제란 체스보드 위에서 그 어떤 퀸도 다른 퀸을 공격할 수 없게 8개의 퀸을 배치하는 방법이다. 사실 이 코드는 퀸의 개수가 4에서 99까지에 대해 전부 작동한다. 이 대회에 관심을 갖고 있다면, IOCCC의 공식 홈페이지인 www.ioccc.org에 직접 방문해보도록 하자.


C을 효과적으로 사용하는 법

C를 효율적으로 사용하기 위해선 C의 장점을 살리되, 단점을 최대한 피하는 데에 있다. 그러한 몇 가지 방법을 소개하도록 한다.

  • 눈에 보이지 않는 실수들을 피하는 방법을 배운다. 이 책에 여러 군데에 이러한 방법이 적혀있다. 이러한 방법은 [!!!] 로 명시하도록 한다. 좀 더 이러한 눈에 보이지 않는 실수들을 알고 싶다면, Andrew Koenig의 C Traps and Pitfalls를 통해 공부할 수 있다. 최근에 나온 컴파일러들은 흔히 나오는 이러한 실수들을 파악해 알려주지만, 이러한 실수들 전부를 다루는 컴파일러는 존재하지 않는다.  
  • 프로그램에 좀 더 의존하기 위해 소프트웨어 도구를 사용한다. C 프로그래머들은 도구들을 매우 자주 만들며, 이를 자주 이용한다. 제일 유명한 C 도구 중 하나는 lint인데, lint는 UNIX 운영체제에서 기본적으로 제공되는 프로그램이다. lint는 대부분의 C 컴파일러들보다 더 광범위한 에러 분석을 제공한다. 만약 lint나 이와 비슷한 프로그램을 사용할 수 있다면, 사용하는 것이 좋다. 다른 유용한 도구는 디버거이다. C 컴파일러는 알다싶이 대부분의 버그를 잡아낼 수 없어 실행에 에러가 발생하거나 잘못된 출력을 하게 된다. 결국 좋은 디버거를 사용하는 것은 C 언어로 프로그래밍하는 사람에게 있어 필수라고 할 수 있다.
  • 이미 존재하는 코드 라이브러리들을 활용하여 코드를 안정화한다. C를 사용함에 있어 이득 중 하나는 하도 많은 사람들이 사용하다보니 그들이 미리 짜놓은 좋은 코드들이 존재한다는 것이고, 이를 활용할 수 있다는 것이다. 이러한 C 코드들은 보통 라이브러리라고 함수들의 집합에 저장되어있는데, 이러한 좋은 라이브러리를 갖고 있는 것은 에러를 줄이는 데에 도움이 될 뿐만 아니라 시간을 절약해 준다. 보통 자주 사용되는 라이브러리들은 많은 사람들이 통상적으로 자주 사용하는 것들인데, 대표적으로 UI 개발, 그래픽, 커뮤니케이션, 데이터베이스 관리와 네트워크 등이 있다. 이러한 라이브러리들은 주로 공용 저작물이거나, 오픈 소스이거나, 상용이다.
  • 실용적인 코딩 버릇을 들인다. 코딩을 할 때의 버릇, 혹은 스타일은 언어 자체에서 강제하는 버릇이 아닌, 스스로 습득하게 되는 것이다. 버릇을 잘 들이면 프로그램이 좀 더 탄탄하고 읽기 쉬우며 유지보수하기 손쉽다. 다른 언어에서도 코딩을 할 때 일정 스타일을 따르는 것은 중요하겠지만 C에서는 특히나 더 중요하다. 위에서도 말했듯, C 언어가 갖는 유연성은 가독성을 떨어뜨린다고 했다. 이 책에서 제시하는 코드들은 단 하나의 스타일을 따를 것이다. 물론 실무에서 사용되는 다른 스타일들이 존재한다. 시간이 된다면 이러한 다른 스타일들을 논해보도록 한다. 어떤 스타일을 배우느냐는 중요하지 않지만, 몇 가지를 배우고 버릇을 들이는 것은 중요하다.
  • 허세 부리지 말고 코드는 간결하게 하라. C에는 여러가지 트릭들이 있다. 보통 프로그래밍을 할 때엔 여러 가지 방법이 있는데, 사람들은 주로 가장 간결한 해답을 고르는 경향이 있다. 그렇다고 너무 나가서 허세 부려서는 안된다. 어쩔 땐 가장 짧은 코드가 가장 이해하기 어려운 코드이다. 이 책에서는 최대한 간결하면서도 가독성 있는 방식으로 코딩을 공부할 것이다.
  • 표준을 지켜라. 대부분의 C 컴파일러는 C89나 C99에 속하지 않는 새로운 C 언어의 기능이나 라이브러리를 지원할 것이다. 허나, 확장성을 위해선 최대한 이러한 새로운 기능은 정말로 필요하지 않는 이상 지양하는 것이 좋다.


Q&A

Q: Q&A 섹션에선 무엇을 하나요?

A: 질문해줘서 감사합니다. 각 단원의 마지막에 나올 Q&A는 다양한 기능이 있습니다.

우선 제일 중요한 기능은 C를 배우는 학생들이 가장 자주하는 질문들에 대해 논하는 것입니다. 독자들 또한 제 C 언어 수업을 듣는 학생처럼 이 Q&A에 참가할 수 있습니다.

다른 기능은 Q&A를 통해 단원에서 다룬 내용에서 좀 더 나아간 부분을 다룰 수 있다는 것입니다. 이 책을 읽는 독자들은 각자 다른 배경지식을 갖고 있을 것입니다. 누구는 프로그래밍을 할 줄 아는 사람일 수도 있을 것이고, 누구는 처음으로 프로그래밍을 배우는 사람일 수도 있을 것입니다. 프로그래밍 경험이 있는 독자들은 간단한 설명과 몇 가지 예제로 만족하지만, 처음 배우는 사람은 그것보단 더 많은 내용을 필요로 할 것입니다. 만약 본인이 단원을 읽고 나서 설명이 모호하다 싶은 부분이 있으면 Q&A에서 좀 더 구체적인 설명을 확인할 수 있을 것입니다.

가끔엔 Q&A에서 C 컴파일러들 사이의 흔한 차이점을 다루기도 할 것입니다. 예를 들자면, 특정 컴파일러에서 제공하는 표준은 아니지만 자주 사용하는 기능들에 대해서 논할 것입니다.


Q; lint의 역할이 뭔가요?

A: lint는 C 프로그램이 발생할 가능성이 높은 에러들이 있는지 확인합니다. 이러한 에러들은 주로 이상한 자료형들의 집합, 사용되지 않은 변수들, 접근 불가능한 코드, 그리고 확장이 되지 않는, 포팅이 되지 않는 코드를 의미합니다. lint는 진단서처럼 프로그래머들이 확인해야할 리스트를 뽑아냅니다. lint의 장점은 컴파일러가 찾아내지 못하는 에러들을 찾아 낼 수 있다는 것입니다. 고로 반드시 lint를 사용하도록 합시다. 물론 lint는 실제 에러의 일부분인 수백가지의 에러에 대한 리스트를 받을 수 있습니다.


Q: lint의 이름의 유래는 뭔가요?

A: 대부분의 UNIX의 이름은 두문자어인데요, lint는 이와는 달리 프로그램에서 에러를 찾아내는 방식에서 이름을 따왔다고 합니다.


Q: lint를 어떻게 다운 받을 수 있죠?

A: lint는 UNIX 표준 도구입니다. 만약 UNIX 운영체제가 아니라면 lint가 없겠군요. 물론 서드 파티들을 위한 lint가 존재합니다. lint의 업그레이드 버전인 splint(Secure Programming Lint) 또한 존재하는데, 이는 대부분의 리눅스 운영체제에 제공될 것이고, www.splint.org에서 다운로드 받으실 수 있습니다.


Q: lint를 사용하지 않고, 컴파일러로 하여금 좀 더 철저하게 일을 하게 강제할 순 없나요?

A: 그런 방법이 존재합니다. 대부분의 컴파일러들은 프로그램을 좀 더 철저하게 확인하는 기능이 있습니다. 코드가 문법이 알맞는가를 확인하는 것에서 더 나아가서 대부분의 컴파일러들은 경고문까지도 출력하여 문제가 발생할 수 있는 지점을 가르쳐주죠. 일부 컴파일러는 단순히 한 가지 레벨의 경고만이 있는 것이 아닙니다. 좀 더 높은 레벨을 선택하면 컴파일러는 좀 더 신중하게 코드를 분석하죠. 만약 본인이 사용하는 컴파일러가 이러한 경고 레벨을 사용한다면, 제일 높은 레벨을 선택하여 사용하는 것이 좋습니다. GCC 컴파일러라고 리눅스에서 기본으로 제공하는 컴파일러에서 에러를 확인하는 옵션은 2단원의 Q&A에서 다루겠습니다.


Q: 저는 제 프로그램이 최대한 안정적으로 만들고 싶습니다. lint나 디버거 말고 또 추가적으로 할 수 있는 도구가 없을까요?

A: 있습니다. 대표적으로 "바운즈 체커bounds-checker"와 "릭 파인더leak-finder"가 있군요. C는 굳이 배열 서브스크립트array subscript를 확인하라고 하지 않는데, 바운즈 체커는 이를 확인해줍니다. 릭 파인더는 메모리 누수를 찾아줍니다. 메모리 누수란 동적으로 할당되지만, 절대로 할당이 해제되지 않는 메모리의 한 블록입니다.




11 11