함수의 반환값에서 함수 어떤 부분의 에러인지 알수 있을까요?

gurugio의 이미지

A라는 함수가 있습니다. A는 B,C,D,E 함수를 호출합니다.
이런 상황에서 보통 A의 반환값은 B,C,D,E의 반환값일 경우가 많고,
B,C,D,E의 반환값은 보통 각각의 함수 내부에서 호출된 시스템 콜의 에러값인 경우가 많습니다.

만약 파일 오픈 에러가 났다면
B에서 파일을 오픈하다가 에러가 난건지, E에서 파일을 오픈하다가 에러가 난건지 어떻게 알 수 있을까요?

보통 에러 값은 어떤 경우에 대한 에러는 말해주지만
어디에서의 에러는 말해주지 않는데
보통 어디에서는 assert를 쓰라고 하지만, 제품에 assert가 들어갈 수는 없으니까요.
에러 값에 "어디에서"를 알 수 있는 정보를 어떻게 넣을 수 있을까요?

powerson의 이미지


그냥 즉각 생각해본 것은, 각 function에 대한 reservation bit를 사용하는 건 어떨까요? 다만, 이렇게 하면, reservation bit 처리에 대한 오버헤드는 발생하겠지만요^^

------------------------------------------------------
아직은 젊다. 모든 것을 할 수 있는 나이란 말이지.

------------------------------------------------------
아직은 젊다. 모든 것을 할 수 있는 나이란 말이지.

madman93의 이미지

B return 1;
C return 2;
D return 3;
E return 4;

^.^
---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

ymir의 이미지

함수를 좀 더 세분화 하여, 메인 로직에서 각각의 함수에 대한 리턴값을 받아 처리하거나..

0 or -1 (with errno) 형태의 함수라면...
기존의 errno 를 활용하여 errno 에 특정 값을 추가 정의하여 활용하거나...

내부적으로 errno 와 유사한 global 구조체 라이브러리를 만들어 사용하는 방법.. 등등..?
set_error(func, line, code, msg) / get_error(&err) 와 같은 형식으로 인터페이스를 정의하면 되겠죠..

함수가 index type 을 리턴하는 게 아니라면...
리턴값이 많아질 수록 caller 가 리턴값에 따라 처리해야 할 가짓수가 많아지므로..
에러코드를 직접 리턴하는 것은.. 1회용이 아니라면 지양하시는 편이..

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

bookworm의 이미지

오류에 따라 알맞는 로직을 추가적으로 실행시키시려면 ymir님 답변처럼 errno 같은 라이브러리를 하나 만드시면 되고 단지 개발자가 확인만 할 것이라면 함수 내부에서 로그로 오류를 기록하게 하면 됩니다.

--

B/o/o/k/w/o/r/m/

B/o/o/k/w/o/r/m/

winner의 이미지

C99에서는 _func_가 있는 것으로 아는데 써본 적은 없고...
얼마나 세밀하게 error 위치를 알고 싶은지는 모르겠는데 위 3가지를 쓰면 될 것이고요.
사실 assert가 __FILE__과 __LINE__을 쓰죠.

제품 사용자에게 위 정보를 알려주시기 싫으시다면 암호화하시거나 hash하시면 되겠죠.

그리고 C에서는 예외처리 지원 언어들처럼 global jumping이 쉽지가 않은 것으로 알고 있습니다.
하지만 말씀하신 것처럼 assert와 같이 바로 종료해도 된다면 exit와 abort를 쓰셔도 되겠죠.
바로 종료하지만 예외처리 logic을 파일에 로깅하거나 화면에 알려주거나 하는 형태로
동적으로 선택하고 싶으시다면 setjmp와 longjmp를 찾아보세요.
저도 써본 적은 없습니다.

unipro의 이미지

반환코드가 많아지면, 반환코드를 관리하고 적절한 반환코드를 찾는데 시간을 허비할 것 같네요.
간단하게는 오류를 관리하는 전역함수와 전역 저장소를 사용하거나, 복잡하게는 자세한 오류를 반환하는 구조체의 사용해보세요.
아래 링크는 참조하세요.
http://library.gnome.org/devel/glib/stable/glib-Error-Reporting.html
----
내 블로그: http://unipro.tistory.com

내 블로그: http://unipro.tistory.com