C++ try/catch 문 이야기

jeongheumjo의 이미지

요즘 후배사원이 아주 날뛰는 통에 회사 생활이 힘들 지경입니다.

//-- 초기화부분
try
{
         someObj.Init(...);
}
catch(TheException e)
{
         //예외처리
}
         try
         {                
                  //-- DB 쿼리
                  someObj.callSomFunc(...);
         }
         catch(TheException e)
         {
                  //예외처리 
         }
try
{
         someObj.Fini();
}
catch(TheException e)
{
         //예외처리 
}

someObj 는 그 친구가 만든 클래스의 객체인데 그 사용 예라고 하면서 위의 코드를 주더라구요.
그래서 물어봤습니다.

someObj.Init(...); 에 대한 예외처리가 끝나고도
someObj.callSomFunc(...); 와
someObj.Fini(); 를 부르는 것인지,

그렇지 않을것 같아서 제가 아래와 같은 제안을 했습니다.

//-- 초기화부분
try
{
         someObj.Init(...);
         try
         {                
                  //-- DB 쿼리
                  someObj.callSomFunc(...);
         }
         catch(TheException e)
         {
                  //예외처리 
         }
         someObj.Fini();
}
catch(TheException e)
{
         //예외처리 
}

someObj.Init(...); 에서 예외가 발생된 경우는
바로 빠져나오는 것입니다.
대신,
someObj.Init(...); 를 성공한 경우는
someObj.callSomFunc(...); 에서 예외가 나더라도
someObj.Fini(); 를 하고 그 이후로 실행이 진행되겠지요.

그러니까 그 친구왈
저더러 C++ try/catch 에 대해 잘 몰라서 이렇게 코딩한 것 같다고 하면서 자기 샘플을 수정해서 전체 메일을 했습니다.

//-- 초기화부분
try
{
         someObj.Init(...);
         someObj.callSomFunc(...);
}
catch(TheException e)
{
         //예외처리 
         someObj.Fini();
         return;
}
someObj.Fini();

그 메일에서 빠뜨리지 않고 아래와 같은 C++ 책에 나오는 얘기를 덧붙였습니다.

C++ try..catch문을 이용하면 실행 코드와 에러처리 코드를 분리 할 수 있는 장점이 있습니다.

(이런 얘기도 덧붙이기는 했습니다.
someObj.Fini(); 는 예외를 던지지 않는다고요.
그래서 try 문에 들어갈 필요는 없다고..
제 판단은, 이 부분이 중요한건 아니라고 봅니다.)

기가 찰 노릇입니다.

여러분은 제 입장이라면 어떻게 하시겠습니까?

그 친구의 메일에 제 답장은 C++ 을 그렇게 잘 알아서 이런 메일을 보냈다는게 황당하기 그지없다는 짧은 답변이었네요..

jick의 이미지

근데 코드 세 개가 다 동작이 다르지 않나요, 뭐가 좋은 코드냐를 정하기 전에 일단 원하는 동작이 뭔지를 정해야 할 것 같은데...

익명 사용자의 이미지


구체적으로 코드로 답변을 제안하기보다는,

문제점을 지적하고,
해결 방법의 힌트만 전체! 메일로 전달하면 어떨까요?
나는 알고 있는데, 직접 찾아봐라 라는 뉘앙스로요..

수정된 코드를 제시하게되면,
후배로서는 간섭받는다는 느낌이 들테고,
코드가 잘 짜졌는지에 대한 평가는 주관적일테니까요..

예를 들어 후배가 새로 전달한 코드에서도,

Init중에 exception이 났는지 Init이후에 났는지에 대한 구분이 안되고,
이 경우 Fini에서 내부에서 다시 예외처리를 해줘야하는 문제점이 있어보입니다.
exception 종류를 나누어 별도 예외처리하도록 하는게 좋겠다..

라는 식으로요..

익명 사용자의 이미지

추가하자면,

님께서 수정 제안하신 코드에서,
실행코드와 예외코드를 나누자는 후배의 지적은 적절해보입니다..
try,catch가 저렇게 nested로 들어가서는
예외처리의 의미가 별로 없어보이네요..

다만 "네가 잘 몰라서 그러는데,"라는 말은 선배에게든 후배에게든 실례가 되겠지요..

후배분께서 의욕이 앞서는 것 같으니..
적당히 인정하실것은 인정하시고, 잘 협력해가시면 좋을듯..

neocoin의 이미지

인용 ~ "저더러 C++ try/catch 에 대해 잘 몰라서 이렇게 코딩한 것 같다고 하면서 자기 샘플을 수정해서 전체 메일을 했습니다."

코드를 떠나서 이부분에서 마음 상하신게 아닌가 싶어요. 서로 의견을 교환하면 이해할 수 있지 않을까 싶습니다.finally 키워드가 없는게 이런 부분에서 골치아프죠..

----

제 의견은 마지막 코드에서 init Fini의 레벨이 차이가 있는 부분 때문에 동의하지 않지만, 두번째 nested 형태로 finally 구현도 복잡도가 높아 보여서 고민이 됩니다.

* http://www2.research.att.com/~bs/bs_faq2.html#finally

그래서 Bjarne Stroustrup 께서 말씀하신 형태의 래퍼 형태의 local variable로 구현하는 것은 어떨까 싶어요.(RAII) 일반화 할수 없겠으나 이런식 말이죠.

try{
    Initiator(someObj);
    //using someObj logic
} catch( init_exception){
} catch( logic_exceptioin ) {
    //exception 처리
}

허나 요즘은 C++안해서리 감이 영 멀어지네요. ;;

hoppang의 이미지

제 생각에도 코드보다는 태도의 문제가 아닌가 싶고요,

저런 경우 똑같은 종류의 예외를 던진다는게 좀 문제가 되지 않나요?
정답인지는 모르겠지만, 저라면 Init과 callSumFunc의 예외를 다른 종류로 할 겁니다.
아니면 예외에 붙는 인자라도 다르게.

winner의 이미지

아, 물론 jeongheumjo 님의 후배가 저는 아닙니다만... 첫번재 예제에서 가운데 try catch가 들여쓰기 되어 있어서 좀 헛갈렸네요.
후배의 의도는 어쨌든 중첩을 하지 말자 이거군요.
그리고 jeongheumjo 님은 예외형식의 추가 없이 try catch 만 바꿔서 제대로 된게 두번째로 생각되어 제안한 거고요.
아마 e-mail에 Fini는 예외를 던지지 않는다는 말을 쓴 것을 보면 후배는 첫번째 예제에서 세번째 예제로 고치면서 level up 은 했군요... -_-.
첫번째와 세번째는 다르니 말이죠.
거기에 맞춰서 또 level up 시켜주는 것이 좋을 것 같습니다. 앞에 나열된 다른 분들의 답변을 통해서요.

다른 사람이 틀려서 고쳐야 할 것이 보일 때 가장 먼저 이루어져야 하는 것은 어떤 상황에서 틀리는지 명백히 보여주는 것으로 보입니다. 그게 QA 부서의 일이기도 한데 source level 에서는 동료 programmer가 해줘야겠죠. 이럴 때 pair programming을 하면 좋은데 사무실 분위기가 가능할지는 모르겠네요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.