[PL] Exception Handling and Event Handling
'프로그래밍 언어' 시리즈
- [PL] Preliminaries
- [PL] Names, Bindings, Type Checking, and Scopes
- [PL] Data Types
- [PL] Expressions and the Assignment Statement
- [PL] Statement-Level Control Structures
- [PL] Subprogram
- [PL] Implementing Subprograms
- [PL] Exception Handling and Event Handling
- [PL] Abstract Data Types and Encapsulation Concepts
- [PL] Object-Oriented Programming
✦ Introduction to Exception Handling
◆ Exception Handling
- Exception (예외) : 프로그램 실행 중 비정상적인 일이 발생했다는 신호
- H/W exception : FP overflow, divide-by-zero, I/O 오류
- S/W exception (compiler 가 생성한 코드) : 배열 range 오류, 사용자 코드 등
- Exception Handling : 예외 감지 후 필요할 수 있는 특별한 처리
- Pre-defined : 암묵적으로 발생
- User-defined : 사용자 코드 의해 명시적 발생
- Exception Handler : 예외 처리 코드 단위
void example() {
...
average = sum / total;
...
return;
/* Exception handlers */
when zero_divide {
average = 0;
printf("Error-divisor (total) is zero\n");
}
...
}
- C : 예외처리 기능 X, 예외 발생 → 제어가 OS 로 넘어가 프로그램 죽어버림
◆ Advantages of Built-in Exception Handling
- 오류 감지 코드 → 작성 번거로움 + 프로그램 어수선하게 함
`if (row >= 0 && row < 10 && col >= 0 && col < 20)
sum += mat[row][col];
else
System.out.println("Index range error on mat, row = " +
row + " col = " + col);
- 예외 처리 기능 존재 → compiler 가 모든 배열 요소 접근 전에 기계어 코드 삽입 가능
→ 소스 프로그램 단축 & 단순화 가능
- Exception propagation → 예외 처리 코드 재사용 가능
- 한 프로그램 단위에서 발생한 예외 → dynamic / static 상위 계층에서도 처리 가능
- 여러 곳에서 발생하는 동일한 예외 모두 처리 가능
- 프로그래머가 다양한 가능한 오류들 고려하도록 장려 → 안정성 ↑
◆ Design Issue
- handler 의 위치 & 범위 : 어디에 작성? 어느 범위의 코드에 적용?
- binding : 임의의 예외 발생 시 어떤 handler 가 처리?
- 정보 전달 : 예외 발생 원인 & 상세 정보 전달?
- continuation vs. resumption : handle 이후 재개? 중단?
- finalization : 어떤 형태의 종료 처리 제공?

✦ Exception Handling in C++
- C++ : 사전 정의된 예외 X
- 예외 → 사용자 or library 의해 정의 & 명시적 발생
- Handler :
try&catch
try {
//** Code that might raise an exception
}
catch (formal parameter) {
//** A handler body
}
...
catch (formal parameter) {
//** A handler body
}
catch: formal parameter 1개만 가능catch블록 적용 범위 → 예외 핸들러의 범위- Example
- C++ → divide-by-zero 직접 예외처리 해야함
// Program to depict how to handle
// divide by zero exception
#include <iostream>
#include <stdexcept>
using namespace std;
// Defining function Division
float Division(float num, float den){
// If denominator is Zero throw runtime_error
if (den == 0) {
throw runtime_error("Math error:
Attempted to divide by Zero\n");}
return (num / den);
}
int main(){
float numerator, denominator, result;
numerator = 12.5;
denominator = 0;
try {
result = Division(numerator, denominator);
// this will not print in this example
cout << "The quotient is "
<< result << endl;
}
catch (runtime_error& e) {
cout << "Exception occurred" << endl
<< e.what();
}
} // end main
- handler 에 예외 바인딩 :
throw [expression]throw로 던진 객체의 타입을 확인, 일치하는 타입의catch블록을 위 → 아래 순서대로 탐색
catch: 매개변수로(...)사용 → type 상관없이 모든 예외 잡음. 마지막에 사용 (모든 예외 잡기 보장)- Unhandled Exceptions
- 함수에서 예외 못잡음 → 점점 위로 올라감
main에서도 처리 X → 프로그램 비정상 종료 → Exception propagation
- Continuation
- handler 실행 완료 후 → try { } 바로 다음 문장
// x = 10, y = 0 인 경우
try {
if(y==0)
throw 10;
count<<"x/y = "<<x/y;
}
catch(int i) { ← 예외 잡힘
count<<"Exception Division by 0";
}
return 0;
// x = 10, y = 2 인 경우
try {
if(y==0)
throw 10;
count<<"x/y = "<<x/y; ← 정상 실행
}
catch(int i) {
count<<"Exception Division by 0";
}
→ return 0; ← catch 이후로 계속
- Evaluation
- 함수 내에서 처리 X 예외 → caller 에게 전파
- 사전 정의된 H/W 예외 X
#include <stdexcept> // standard exception types
class Fraction {
int numer_;
int denom_;
public:
explicit constexpr
Fraction (int numerator, int denominator):
numer_{numerator}, denom_{denominator}
{
if (denom_ == 0)
throw std::invalid_argument{"denominator must not be zero"};
}
...
};
int main () {
try {
int d = 1;
std::cin >> d;
Fraction f {1,d};
...
}
catch (std::invalid_argument const& e) {
// deal with / report error here
std::cerr << "error: " << e.what() << '\n';
}
...
}
- Example 2
#include <iostream>
#include <stdexcept>
void func3(int input) {
if (input < 10)
throw std::runtime_error("Exception in func3");
}
void func2(int input) {
func3(input);
}
void func1(int input) {
func2(input);
}
int main(int argc, char* argv[]) {
int input = std::stoi(argv[1]);
try {
func1(input);
} catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
- func3 에서 예외 발생 시 func2, func1 나머지 부분 실행 X
✦ Exception Handling in Java
- Java Virtual Machine (JVM) : 암묵적 발생 사전 정의된 예외 모음 포함
- Classes of Exceptions
- 모든 예외 →
Throwable클래스의 자손- Error
- Java interpreter 가 throw (ex. heap overflow)
- 사용자 프로그램에서 처리 X
- Exception
- IOExeption :
java.io패키지에서 입출력 연산 중 오류 발생 시 thrown - RuntimeException : 배열 range, null pointer 문제 등
- 사용자 정의 예외
- IOExeption :
- Error
- 사용자 정의 예외는 Exception 상속
- 모든 예외 →
- Java Excpetion Handler
- 모든 catch → 이름이 있는 parameter 요구. 모든 parameter 는 throwable 의 자손.
try&catch→ C++ 과 동일try: 예외 발생 가능 코드catch: 예외 처리 코드
- 예외 →
throw new MyException();(new 연산자 이용 객체 생성) finally: 예외 발생 여부 관계없이 항상 실행되는 블록
public class Main {
public static void main(String[] args) {
try {
int[] myNumbers = {1, 2, 3};
System.out.println(myNumbers[10]);
} catch (Exception e) {
System.out.println("Something went wrong.");
} finally {
System.out.println("The 'try catch' is finished.");
}
}
}

✦ Exception Handling in Python
try:
my_file = open('0001-Copy1.1999-12-10.farmer.ham.txt', "r")
file_content = my_file.read()
except NameError:
print("Undefined variable is used!!")
else:
print("Content read successfully.")
finally:
my_file.close()
print("File is closed.")
## Content read successfully.
## File is closed.
try: 이 코드를 실행except: 예외 발생 시, 이 코드를 실행else: 예외가 없으면, 이 코드를 실행finally: 마지막에 항상 이 코드를 실행
# 다중 except 블록
try:
num1 = int(input("enter value of number1: "))
num2 = int(input("enter value of number2: "))
result = num1/num2
print(result)
except ValueError:
print("Not valid number")
except ZeroDivisionError:
print("Number Cannot be Divided by Zero")
except:
print("This is the Generic Error")
sys.exc_info()[0]: 현재 발생한 예외의 class 타입 반환하는 함수
# define Python user-defined exceptions
class InvalidAgeException(Exception):
"Raised when the input value is less than 18"
pass
# you need to guess this number
number = 18
try:
input_num = int(input("Enter a number: "))
if input_num < number:
raise InvalidAgeException
else:
print("Eligible to Vote")
except InvalidAgeException:
print("Exception occurred: Invalid Age")
raise: Java/C++ 의throw. 사용자가 직접 예외 발생시킬 때 사용
#!/usr/bin/python
# -*- coding: utf-8 -*-
try:
retval = 10/0
except ZeroDivisionError as e:
pass
except ... as: 발생한 예외 객체를 변수에 담아 사용catch(Exception e)에서e에 해당
pass: 아무것도 하지 않음- 예외 잡았지만 별도 처리 없이 넘어가고 싶을 때 사용
✦ Introduction to Event Handling
◆ Event Handling
- Event : 특정한 일이 발생했다는 알림 (click, drag, key 입력 등)
- Event Handler : Event 에 반응해 실행되는 code segment
- Event Handling : exeception handling 과 유사
- 공통점 : Handler 는 암묵적으로 호출 (by. event, exeception)
- 차이점
- exception : 사용자 코드 의해 명시적 / 하드웨어 & 소프트웨어 interpreter 의해 암묵적으로 생성
- event : 외부 행동 (GUI 로 사용자 상호 작용) 으로 인해 생성
◆ Event Driven Programming Model
- 프로그램이 event 에 의해 실행 → 유저가 정확히 언제 실행할지 예측 불가능

공유하기
Twitter Facebook LinkedIn글 이동
시리즈 이동
Comments