버그를 없애기 위한 C 프로그래밍

2008. 7. 19. 23:08 컴퓨터/컴퓨터 이야기

아래에 간단한 C 프로그램이 있습니다. 버그가 하나 숨어 있는데, 보이시나요? 프로그램을 컴파일해 보면 아무 이상이 없고, 에러 없이 실행되지만 엉뚱하게 행동합니다.

#include <stdio.h>         // printf()
#include <string.h>        // strlen()
#include <fcntl.h>         // O_WRONLY
#include <unistd.h>        // write(), close()

int main()
{
   char  *temp = "forum.falinux.com";
   int    fd;

   fd = open( "./test.txt", O_WRONLY ¦ O_CREAT ¦ O_EXCL, 0644);
   if ( fd = -1)
   {
      printf( "파일 열기에 실패했습니다.n");
   }
   else
   {
      write( fd, temp, strlen( temp));
      close( fd);
   }
   return 0;
}

혹시 아시겠습니까? 네, 맞습니다. fd 값이 -1인지 확인하는 if 절이 잘못되었습니다. 올바르게 고친다면 fd = -1 이 아니라 fd == -1 이 되어야 합니다. C 언어를 사용하다 보면 흔하게 겪는 에러인데, 컴파일할 때에도 걸러지지 않기 때문에 if 절에서 = 를 사용할 때면 매우 조심합니다.

너무 당연한 문장은 모두 읽기도 전에 다음 문장으로 이동하기 때문에 더욱 보이지 않을 때가 있습니다. 혹 아래의 문장을 아시나요?

캠릿브지 대학의 연결구과에 따르면, 한 단어 안에서 글자가 어떤 순서로 배되열어 있는가 하것는은 중하요지 않고, 첫째번와 마지막 글자가 올바른 위치에 있것는이 중하요다고 한다. 나머지 글들자은 완전히 엉진창망의 순서로 되어 있지을라도 당신은 아무 문없제이 이것을 읽을 수 있다. 왜하냐면 인간의 두뇌는 모든 글자를 하나 하나 읽것는이 아니라 단어 하나를 전체로 인하식기 때이문다.

글 내용이 이상하죠? 이상하지 않나요? 이상한 점을 못 보셨다면 글을 다시 한자 한자 다시 보세요. 이제 이상한 것이 보이시나요?

이렇게 눈으로 언뜻 보면 제대로 인식하지 못하는 경우가 있습니다. 그러다 보니 매우 긴 프로그램 소스를 보다 보면 if 절의 == 비교가 = 로 오타를 해도 나중에 이것이 보이지 않아 고생하게 되는 것이죠.

파스칼에서 대입문은 :=

처음 파스칼을 입문했을 때, 대입문을 := 로 한 것을 보고, 파스칼 언어를 만든 사람의 세심한 배려에 감탄합니다. 대입은 := 이지만 두 개의 값을 비교할 때에는 = 를 사용합니다. 그러므로 C에서와 같이 오타를 해도 컴파일러에 의해 에러를 검출해 냅니다.

저는 그래서

이런 경험을 하고부터는 상수를 항상 오른쪽이 아닌 왼쪽에 두는 버릇이 생겼습니다. 즉, 아래와 같이 상수를 오른쪽에 두는 것이 아니라,

if ( fd = -1)

이렇게 왼쪽에 둡니다.

if ( -1 = fd)

이렇게 상수를 왼쪽에 두면, == 를 = 로 오타로 입력했다 해도 컴파일 에러가 발생하여 버그를 미리 잡아낼 수 있습니다. 이런 이유 때문에 == 말고도 다른 비교에서도 모두 상수는 왼쪽에 두는 버릇이 생겼습니다. ^^

이 댓글을 비밀 댓글로
  1. 캠릿브지 대학의 연결구과...
    저도 모르게 술술(?) 읽어내려가 버렸네요~
    • 꼬마별
    • 2008.07.20 00:51
    저도.. 캠릿브지부터 술술 내려갔다는..
    저거 스펀지에서 봤는데.. 한국말 잘하는 외국인도 저거 읽을줄 안다네요..

    그런데.. 주인장님 질문이 있습니다만;

    티스토리를 신청하면 무조건 웹호스팅을 신청해야 하나요?
    • 외국인도 그렇군요. ^^

      티스토리에서 웹서버 공간까지 모두 제공하므로
      블로그를 운영하기 위해 따로 준비할 것은 없습니다.
      웹 주소를 다른 주소로 변경하시는 것만 직접 도메인을 구하시고
      설정하셔야 되는데, 저는 tistory 주소 그대로 사용하는 것이 더 좋더군요. ^^
    • sena
    • 2008.07.20 01:17
    상수를 왼쪽에 두는 팁 하나 배워 갑니다. 많이 고민했는데.. --;
  2. 전자공학도로써 심히 공감이 되는 글입니다. ㅎㅎㅎㅎㅎ 재밌게 잘읽었네요 ^^



    아! 전자공학도가 납땜질만 할것이라는 생각하시는 분도 계시겠지만...

    전자공학도는 납땜뿐만 아니라.. 코딩도 잘해야 된다는...

    마이크로 컨트롤러 8051, ATMEGA128, ARM core 펌웨어 만들려면 C언어 무지 잘해야 되요.. ㅠㅠ
  3. 8051이라 오랫만에 듣네요...^^; C언어에서 저런 실수가 발생하는군요...ㅡ.ㅡ;;
    좋은말씀 감사드립니다...공부하는데 참고하겠습니다...^^;
    캠브리지의 저글은 정말 언제봐도 신기해요 요전에 어떤분의 블로그에서 본기억이있는데 정말 신기...^^;
    저도 그냥 모르고 술술 넘어갔어여...^^;
    • 찔찔이
    • 2008.07.20 19:04
    와.. 비교할땐 상수를 왼쪽에 두는 방법이 있군요, 좋은거 하나 배워갑니다. C입문할때 저거 하나 못찾아서 멍때렸던 적이 기억나네요 ㅋㅋ
    • 얼룩고양이
    • 2008.07.21 11:46
    제목을 보고 글의 머릿말만 딱 읽고 나서 이거 if문의 오류를 찾아내라는 문제일거라고 생각했는데~
    딱 맞았네요~ 제일 많이 생기는 오류이면서 제일 찾기 힘든 오류라는것은
    프로그래머라면 모두 공감하는 이야기이니깐요...ㅋㅋㅋ
    그래서 if문에서 상수를 오른쪽에 두는것도 오래전 정설로 되어있는 이야기이기도 하지요~
    하지만 아직 그게 낯설어서 그렇게 사용하고 있지는 않지만
    프로그래머용 에디터인 Source Insignt에서는 '='와 '=='를 구별해주기위한 배려가 있군요~
    옵션에서 설정을 하면 에디터화면에
    = 는 ← 로
    != 는 ≠
    기타 대소비교에 해당하는 표시도 하나의 특수문자로
    표시등등 설정을 할 수가 있군요~
    이렇게해서 사용하니 실수를 안하게 되네요~
  4. gcc 같은 경우는 옵션을 '-Wall'(모든 경고 다 보기 옵션)으로 하면, 다음과 같이 warning을 볼 수 있습니다. (gcc 3.4.6에서 테스트하였습니다.)

    $ gcc -Wall test.c
    test.c: In function `main':
    test.c:12: warning: suggest parentheses around assignment used as truth value

    고로 '-Wall' 옵션은 필수! ;)
    비쥬얼 스튜디오는 해본 지 오래돼나서...
    • kaze
    • 2008.07.22 08:27
    일부 마이컴 컴파일러에서는 저렇게 하면.. 혹 '==' 쓰려고 했더거 아니냐라고 되묻고 에러 메세지를 내보내지요~
    • 좋은날
    • 2008.07.24 09:07
    저런건 정말 찾기 어렵겠네요...
    추천
  5. 그래서 저도 pascal 을 좋아합니다. 문법이 아주 명확하거든요.

    pascal 이 소스를 작성할 때는 좀 까다롭지만, 만들어진 소스를 읽기는 쉽죠.
    • AHaah
    • 2010.05.31 22:13
    이 상냥한 설명 ㅠㅠ
    감사합니다 ㅠㅠ
  6. 아~~

    저런 방법도 있네요 ^^

    잘 봤습니다.
    • ^^
    • 2011.05.11 10:24
    예전에 한 번 찾아왔었는데(==문제로!!!) 오늘 또 찾아와서는 아~ 이거 봤었는데~ 했네요^^;; 이럴 수가ㅠㅠㅎㅎ 많은 도움이 돼요 자주!!!ㅎㅎ