리눅스 커널을 공부하다가 커널단에서 goto문이 쓰이는걸 보고, 예전에 모듈을 작성할때 에러처리 부분에서 goto문을 쓰다가 팀장님에게 혼났던 기억이 나서 책에서 소개하는 논문을 한번 봤다.
Go To Statement Considered Harmful
최단경로 알고리즘으로 알려진 유명한 다익스트라(Dijkstra)의 논문이다.
이 논문과 관련자료검색을 해보면서 느낀거지만, goto문 자체에 대해서 완전 부정이 아니라는것을 알았다.
내가 이해한 바로는 사람이 코드를 작성할때 절차에 중점을 두고 ‘라인 by 시간’으로 작성을 한다. 그런데 goto문을 쓰면서 그 시간축을 무시하기 시작하면 그 코드는 이해못할 코드가 되어 버린다는 것이다. (이 의미가 다익스트라가 말한것과 같은지는 모르지만….)
그런데 에러 처리시 이런 코드를 쓴다면 다익스트라의 논문에 반기를 드는 것인가?
[CODE c]
int many_malloc(char **a, char **b, char **c){
*a = (char*)malloc( sizeof(char) * 10);
if( !(*a) ) goto err1;*b = (char*)malloc( sizeof(char) * 100);
if( !(*b) ) goto err2;*c = (char*)malloc( sizeof(char) * 1000);
if( !(*c) ) goto err3;
return 1;err3:
free(*b);
err2:
free(*c);
err1:
return 0;
}
[/CODE]
만일 이런 코드를 예로 든다면 두번째나 세번째 malloc시 여러번의 free작업을 수작업으로 해줘야 하고 같은 코드를 한 모듈에 여러번 작성을 해야할지도 모른다.
게다가.. 다익스트라가 이야기한 그런 시간축으로 봤을때 goto문으로 쓴 에러처리 모듈은 마지막에 항상 존재하므로 코드를 읽는 사람에게 큰 부담도 가지 않을것이다.
가장 큰 문제는 goto문의 레이블이 코드 중간에 떡하니 존재할때 생긴다고 생각한다. 그런 코드는 코드를 보면서 어떻게 흘러가는지 예측하기 힘들다.
다익스트라의 논문의 주제는 라인을 시간의 축으로밖에 생각하지 못하는 인간의 인지능력의 한계에 적응하고자 goto문의 사용을 제한하라는 것이지, 절대 쓰지 말라는 뜻은 최소한 아닌거 같다.
이런거 말구, if문에다가 if문 그 안에 else문을 남발하는게 goto문 한번쓰는것보다 해악이 있을거라는 생각이 든다.
그래서 결론은 goto문은 함께 프로젝트 하는 사람들과 합의를 도출해서 “다중 malloc시 에러처리”와 같은 한정적인 용도로 사용하는게 좋다는게 나의 생각이다. 그러면 코드의 간결함에 기여도 할 것이며, 따라서 코드의 가독성도 높아지기 때문이다. 또한 유용하게 쓴다면 flag변수를 설정하지 않아도 되는 경우도 있으니 이런 적절한 도입 사례는 찾아보기 나름이고 적용하기 나름인거 같다.
ps. goto문을 이유없이 쓰지 말라구 말했던 수많은 책들에 이런 내용이 있다면 좋았을텐데…
goto문에 대한 Dijkstra의 논문을 보며. by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.