290 likes | 434 Views
Chapter 11 – 예외 처리. Outline 11.1 설계 쟁점 11.2 Pl/I 의 예외 처리 11.3 Ada 의 예외 처리 11.4 C++ 의 예외 처리 11.5 java 의 예외 처리. 11.1 설계 쟁점. Procedure 의 종료 return ( 정상 ), goto overflow, underflow, range error - system interrupt EOF 등 예외조건 ( 예상 가능한 조건 ) 해결 방법 예외조건 제어 불가능 언어
E N D
Chapter 11 – 예외 처리 Outline 11.1 설계 쟁점 11.2 Pl/I의 예외 처리 11.3 Ada의 예외 처리 11.4 C++의 예외 처리 11.5 java의 예외 처리
11.1 설계 쟁점 • Procedure의 종료 • return (정상), goto • overflow, underflow, range error - system interrupt • EOF 등 예외조건 (예상 가능한 조건) • 해결 방법 • 예외조건 제어 불가능 언어 • 오류 시 약속된 값 반환 - Programmer 매번 check • 오류 처리 루틴으로 즉시 제어 이동 (정상제어 파괴) • 예외조건 제어 가능 언어 • 사용자 제어 가능 • PL/I : 최초 제공 언어 • MESA, CLU, Ada, C++, Java : 우아한 방법 제공
11.1 설계 쟁점 • 예외 처리 • 프로시저들 사이의 정보 교환 • 일반적인 호출 반환과 다름 • 프로시저들간의 특별한 제어 허용 • 예외란 오류가 아님 • 초기 예외 처리 • Hardware interrupt routine을 사용 • system에서 제공 : 종류, 처리 루틴 • 예외 처리시 고려해야 할 쟁점들 • 어떤 프로시저가 발생된 예외를 처리할 것인가? • 예외 처리 후 예외 발생 프로시저의 활성화 지속 여부?
11.1 설계 쟁점 • 어떤 프로시저가 발생된 예외를 처리? • 활성화된 procedure중에서 결정하는 방법
11.1 설계 쟁점 • 예외 처리의 주요 쟁점 • System interrupt 접근 방법이 제공되었는가? • System interrupt를 사용자가 새로 정의하여 우선 시킬 수 있는가? • 사용자 정의 예외가 가능한가? 이 예외를 어떻게 발생시키는가? • 가능 예외(enable exception)의 영역 규칙은 무엇인가? • 예외 처리(exception handler)의 영역은 어디인가? • 예외를 발생시킨 프로시저를 실행 재개시키는가 종결시키는가? • 발생된 예외의 전파(propagation)는 어떻게 되는가? • 한 예외에 매개 변수를 사용하여 다양화 시킬 수 있는가? • (예기치 않았던) 모든 예외를 한번에 자동 처리할 수 있는가? • 예외 처리 루틴에서 예외를 발생 시킬 수 있는가? 이 때 후속 처리는?
11.2 PL/I의 예외 처리 • 시스템 제공 on condition(조건)만 사용 가능 • 수치계산 condition : default enable 1. CONVERSION 2. FIXEDOVERFLOW 3. OVERFLOW 4. UNDERFLOW 5. ZERODIVIDE • Program test condition : default disable 6. SIZE 7. SUBSCRIPTRAGE 8. STRINGRANGE 9. CHECK 10.AREAR • 입출력 condition : always enable 11. ATTENSION 12. CONDITION 13. ENDFILE 14. ENDPAGE 15. ERROR 16. FINISH 17. KEY 18. NAME 19. PENDING 20. RECORD 21. TRANSMIT 22. UNDEFINITEFILE
11.2 PL/I의 예외 처리 • 예외 조건 상태 제어 (가능/불능) • enable 선언 : condition 이름 (prefix 사용) • disable 선언 : NO + condition 이름 (prefix 사용) • 예) (NOUNDERFLOW, STRINGRANGE) disable enable • 예외 조건 영역 (scope) • 문장 - 한 문장만이 예외 조건 영역 • if문 - condition field만 영역 적용 • procedure, begin -end - 해당 블록 (inner 블록은 상속)
11.2 PL/I의 예외 처리 • 예외 처리 루틴 (Exception Handler) • 표준 시스템 예외 처리 루틴 : default - user overruling 가능 • 예외 처리 루틴 사용자 정의 ON condition-name <on-unit> <on-unit> : 사용자 정의 예외 처리 루틴(문장 또는 블록) • 예외 처리 수행 후 (제어 이동) • 예외를 발생 시킨 문장 • 예외를 발생 시킨 문장 다음 문장 • handler에서 별도로 분기 가능 • 예외 발생 (enable 상태 예외만 가능) • 시스템에서 자동 발생 • 사용자 발생 SIGNAL condition-name SIGNAL condition-name (identifier) : 사용자 정의 예외 취급 가능
11.2 PL/I의 예외 처리 1 TEST:PROCEDURE OPTIONS(MAIN); 2 DECLARE (PERSON , GRADE) FIXED; 3 DECLARE LAST FIXED INIT(0); 4 DECLARE SUMMARY(1:50 , 0:100) FIXED; 5 ON ENDPAGE(SYSPRINT) /* 오류 메시지 리스트를 위한 제목 인쇄 */ 6 BEGIN PUTPAGE; PUT LIST(' ' , 'LIST ERROR DATA'); END; 7 ON SUBSCRIPTRANGE BEGIN 8 IF LAST = 0 THEN SIGNAL ENDPAGE(SYSPRINT); 9 /* 오류가 첫 번째로 발견되면 오류 리스트의 제목 인쇄 */ 10 IF I NOT = LAST THEN /* 새로운 경우를 검사 */ 11 PUT SKIP DATA(I , PERSON , GRADE); 12 LAST = I 13 END; 14 ON ENDFILE(SYSIN) BEGIN; 15 PUT PAGE LIST(' ' , ' ' , `OUTPUT FOR CLASS'); 16 PUT SKIP LIST(' ' , ' ' , 'SUMMARY'); 17 PUT SKIP(3) LIST(SUMMARY); 18 IF LAST NOT = 0 THEN PUT SKIP(4) LIST 19 ('SOME DATA IS INCOMPLETE, SEE OUTPUT'); 20 END; 21 SUMMARY = 0; 22 A:DO I = 1 BY 1; 23 GET LIST(PERSON , GRADE); 24 SUMMARY(PERSON , GRADE) = SUMMARY(PERSON , GRADE) + GRADE; 25 END A; 26 END TEST;
11.2 PL/I의 예외 처리 • PL/I ON 문의 문제점 • 예외 발생 • 어떤 handler가 처리(dynamic link) • 정적 영역을 벗어나므로 예측 불허 • 해결책 : 예외 처리 루틴 제공 (해당 프로그램 내) • 비지역 테이블로 분기 동작 발생 가능 • open된 file들을 close하지 못함 • 계산형 예외 조건 불일치 • OVERFLOW, SUBSCRIPTRANGE : 반환 불허 • UNDERFLOW, STRINGRANGE : 반환 • disable condition • 조건을 검사하지 않을 뿐 • 조건 발생 : 오류로 취급되어 나머지 프로그램 실행 미정의
11.3 Ada의 예외 처리 • Steelman Requirements - Ada의 예외 처리에 대한 명세 • 예외 처리 실행 후, 발생 블록 실행 재개 안 함 • 다수의 미리 정의된(predefined) 예외 제공 - 시스템 환경 • Ada의 미리 정의된 예외 종류 • CONSTRAINT-ERROR : 영역, 첨자, 열거형 자료 등에 대한 제한 이탈, null 접근 시 • NUMERIC-ERROR : 연산 결과가 영역을 벗어날 때 • SELECT-ERROR : select문에서 택일 조건 모두가 만족되지 않을 때 • STORAGE-ERROR : 기억 장소를 할당할 수 없을 때 • TASKING-ERROR : 태스크간에 통신 할 때
11.3 Ada의 예외 처리 • Ada의 사용자 정의 예외 • exception선언문 • 예) BAD_FORMAT, TIMEOUT, XXX : exception • 예외 발생 • 자동 발생 (시스템 정의 예외) • 사용자 발생 (raise문 이용) • 예) raise TIMEOUT
11.3 Ada의 예외 처리 • 예외 처리 루틴 • 시스템 제공 예외 처리 • 사용자 예외 처리 루틴 재 정의 가능 (우선) • 사용자 정의 예외 처리 루틴 작성 형태 <exception-handler> ::= when <exception-choice>{|<exception-choice>} => <statements> <exception-choice> ::= <exception-name> | others • 예외 처리 순서 예외 발생 프로그램 예외 처리 루틴 존재 해당 루틴에서 처리 예외 처리 루틴 부재 caller로 예외 전파 (dynamic) 예외 처리 후 제어는 예외 처리 루틴이 제공된 프로그램의 caller로 반환
11.3 Ada의 예외 처리 begin -- this is a sequence of statements exception when NUMERIC_ERROR => -- 수치 오류를 처리하는 작업 when BAD_FORMAT => -- 어떤 예외 처리 작업 when others => -- 위 두 예외를 제외한 모든 예외를 처리하는 작업 end; < Ada 예외 처리 루틴 구문 예 >
11.3 Ada의 예외 처리 < Ada 예외 처리 예 > 1 procedure P is 2 BAD-FORMAT:exception; 3 procedure Q is 4 begin 5 . . . 6 if S /='' then raise BAD_FORMAT;end if; 7 . . . 8 end Q; 9 procedure R is 10 begin 11 Q; 12 exception when BAD_FORMAT => -- handler body 1 13 end R; 14 begin 15 R; 16 Q; 17 exception when BAD_FORMAT => -- handler body 2 18 end P;
예외사항 발생 11.3 Ada의 예외 처리 • 예외 사항의 전파 • 예외사항이 발생되었지만 해당 예외처리기가 없는 경우는 호출한 상위 프로그램으로 제어가 넘어감 예외의 전파 (Propagation of Exception)
11.3 Ada의 예외 처리 < Ada 예외 전파 사용 예 > 1 procedure A is 2 procedure B is 3 FLOPPED :exception; 4 begin 5 -- sequence of statements 6 exception when FLOPPED => raise end; begin B; exception when others => -- handle FLOPPED if possible else raise; end;
11.3 Ada의 예외 처리 1 procedure DOSOMETHING is 2 HANDLE_ERROR:exception; 3 begin 4 -- perform some set of actions 5 exception 6 when HANDLE_ERROR => -- error handing code 7 end; 8 end DOSOMETHING; 9 function SECURE_DIVIDE(X , Y:REAL) return REAL is 10 begin 11 return X / Y; 12 exception 13 when NUMERIC_ERROR => return 0; 14 end SECURE_DIVIDE; 15 procedure COPYOVER is 16 begin 17 OPEN(INFILE); 18 OPEN(OUTFILE); 19 loop 20 GET(INFILE , CHARACTER); 21 PUT(OUTFILE , CHARACTER); 22 end loop; 23 exception 24 when END_OF_FILE => 25 PUT(OUTFILE , EOF); 26 CLOSE(OUTFILE); 27 CLOSE(INFILE); 28 end COPYOVER; < Ada에서의 다양한 예외들의 사용 예 >
11.4 C++의 예외 처리 • C++의 예외 처리기 형식 • try 구성 복합문(예외 발생)과 다수의 catch 복합문(예외 처리 루틴)으로 구성 • 예외 처리 루틴 catch문 • 함수 형태 • 형식 매개 변수 오직 한 개(경우에 따라 생략 가능) try { -- 예외가 발생하기를 기대하는 코드 } catch (formal parameter) { -- 예외 처리기 몸체부 } . . . catch (formal parameter) { -- 예외 처리기 몸체부 }
11.4 C++의 예외 처리 • 사용자 정의 예외만 존재 • 시스템 예외 처리 불가능 / disable도 불가능 • 함수에서 발생할 수 있는 예외의 자료형 선언 가능 • 예) int fun() throw (int, char *) { … } • 예외 전파 - 동적 연결 • 형식매개변수 생략형 예외 처리 • catchall - Ada의 others에 해당 • 명시적 예외 발생 • throw 문
#include <iostream.h> • void main() { //* 어떤 예외도 발생 가능 • int new_grad, index, limit_1, limit_2, freq [10]; • short int eof_condition; • try { • while (1) { • If (!cin >> new_grade) //* cin이 eof를 만나면 • throw eof_condition; //* eof_condition 예외 발생 • index = new_grade /10; • { try { • if (index < 0 || index > 9) • throw (new_grade) ; • freq [index]++; • } //* 속 try 복합문 끝 • catch (int grade) { //* 첨자 오류 처리기 • if (grade == 100) • freq [9]++; • else • cout << “ Error -- new grade : “ << grade • << “ is out of range “ << end1; • } //* catch(int grade) 끝 • } //* 속 try 복합문과 catch문 쌍 끝 • } //* while 문 끝 • } //* 밖 try 복합문 끝 • catch (short int) { //* eof 예외 처리기 • cout << “ Limits Frequency ” << end1; • for ( index = 0 ; index <10 ; index++) { • limit_1 = 10 * index; • limit_2 = limit_1 + 9; • if (index == 9) • limit_2 = 100; • cout << limit_1 << limit_2 << freq [index] << end1; • } //* for 문 끝 • } //* catch(short int) 끝 • } //* main 끝 { try { if (index < 0 || index > 9) throw (new_grade) ; freq [index]++; } //* 속 try 복합문 끝 catch (int grade) { //* 첨자 오류 처리기 if (grade == 100) freq [9]++; else cout << “ Error -- new grade : “ << grade << “ is out of range “ << end1; } //* catch(int grade) 끝 } //* 속 try 복합문과 catch문 쌍 끝
11.4 Java의 예외 처리 • 예외의 종류 • 시스템 정의 예외(System-defined exception or predefined exception) • 프로그램의 부당한 실행에 의한 예외 • 비검사 예외(unchecked exception) • Error와 RuntimeException 클래스 • ArithmeticException, IOException, IndexOutOfBoundsException, ArrayStoreException, NegativeArraySizeException, NullPointerException, SecurityException, IllegalMonotorException등… • 프로그래머 정의 예외(Programmer-defined exception) • 프로그래머에 의도적으로 야기되는 예외 • 검사 예외(checked exception) : 예외 처리기의 존재 검사
Object Throwable LinkaqeError ThreadDeath Error Exception VirtualMachineError RuntimeException CheckedException ArithemticException 11.4 Java의 예외 처리 < Throwable 클래스의 계층 구조 >
11.4 Java의 예외 처리 • 자바 예외 처리기 • C++ 예외 처리기와 동일한 형태 • catch문은 매개변수를 갖는다 • 클래스는 미리 정의한 클래스 Throwable의 후손이어야 함 • class MyException extends Exception { • public MyException( ) { } • public MyException(String message) { • super(message); • } • } 예외 정의 • MyException myExceptionObject = new MyExeption( ); • … • throw myExceptionObject; • 또는 • throw new MyException(“Here is HongKilDong”); 예외 발생
11.4 Java의 예외 처리 • 예외 처리 바운딩 • try구문에서 발생한 경우 • catch 함수의 매개변수 • 발생된 예외 객체나 발생된 예외 객체의 조상 • 정적 바인딩 • 내포한 상위 try 구문의 처리기 탐색 • 동적 바인딩 • 메소드의 호출자에게 전파 • Java의 throw절 • C++의 throw절과 유사하지만 의미는 전혀 다르다. • Java throw절에 있는 예외 클래스 이름의 의미 • 그 예외 클래스 또는 후손 예외 클래스가 그 메소드에 의해서 발생될 수 있다는 것을 지정
11.4 Java의 예외 처리 • 비검사 예외 • 컴파일러가 전혀 관계하지 않는 예외 • 클래스 Error와 RuntimeException, 그 후손 클래스들의 예외 • 검사 예외 • 메소드에서 발생시킬 수 있는 모든 검사 예외를 throws절에 나열했는지 또는 메소드에 나열했는지를 컴파일러가 확인하는 예외
Import java.io.*; Class NegativeinputException extends Exception { //** 자료 끝을 다루는 예의 정의 public NegativeInputException () { System.out.println(“End of input data reached”); } //** 생성자 끝 } //** NegativeInputException 클래스 끝 Class GradDist { int newGrade, index, limit_1, limit_2; int [] freq = {0,0,0,0,0,0,0,0,0,0}; void buildDist () throws IOException { DataInputStream in = new DataInputStream(System.in); } //** method buildDist 끝 Try { while (true) { systme.out.println(“Please input a grade”); newGrade = Integer.parseInt(in.readLine()); if (newGrade < 0) throw new NegativeInputException(); index = newGrade /10; } //** while(true) ..문 끝 } //** 바깥쪽 try절 끝 Catch (NegativeInputException) { System.out.println (“\nLimits Frequency\n”); for (index=0; index<10;index++) { limit_1 = 10 * index; limit_2 = Limit_1 + 9; if (index ==9) limit_2=100; System.out.println(“ “+limit_1 + “-” + limit_2 + “ “ + freq[index]); } //** for 문 끝 (index = 0;.. } //** catch 문 끝 (NegativeInputException.. try { freq[index]++; } //** 안쪽 try절 끝 catch (ArrayIndexOutOfBoundsException) { if (newGrade ==100) freq[9]++; else System.out.println(“Error – new grade : “ + newGrade + “ is out of range”); } //** catch(ArrayIndex..)절 끝
11.4 Java의 예외 처리 • finally 절 • 프로세스가 반드시 실행되어야 할 상황이 존재하는 경우 • 폐쇄(close)되어야 할 파일 • 메소드에 제공된 외부 자원을 해제해야 하는 경우 try { … } catch(…) { … } …//** More handlers finally { …… }
11.4 Java의 예외 처리 • C++의 예외처리보다 개선된 점 • 발생될 수 있는 객체와 프로그램에 있는 모든 다른 객체를 구분 • 머리부로부터 발생할 수 있지만 처리하지 않은 예외를 알 수 있다. • finally절의 추가로 복합문이 종료되는 것에 상관없이 청소작업이 발생하는 것을 허용한다. • 사용자 예외 처리기에서 처리될 수 있는 여러가지 시스템 예외를 묵시적으로 발생시킨다.