Summary

동료 평가에서 예외 처리의 기준에 대한 이야기가 많이 이루어지는 것 같습니다. 하지만 그 이전에 예외의 정의에 대한 이야기가 선행되어야 할 것 같습니다. 제가 알고 있는 수준에서 정의된 동작, 지정되지 않은 동작, 정의되지 않은 동작, 예외에 대한 이야기를 공유해보고자 합니다.

Function

함수는 집합 간의 방향성이 있는 대응 규칙입니다. 이 때 대응 관계에서 정의역의 원소를 결정자(Determinant), 치력의 원소를 종속자(Dependent)고 부릅니다.

하나의 결정자에는 반드시 하나의 종속자가 대응되어야 합니다. (복수의 결정자에 동일한 종속자가 대응할 수는 있습니다.) 우리가 구현하는 함수도 동일한 입력에 대해서는 항상 유일한 출력값을 반환해야합니다.

Defined Behavior

입력값이 정의역의 원소이고 출력값이 유일하다면 출력값은 정의된 행동입니다. 우리가 함수의 ‘기능’이라고 부르는 것이 바로 정의된 행동입니다.

프로그래밍 언어에서 정의된 행동은 어떠한 Statement가 반드시 하나의 Instruction set으로 generate될 수 있음을 의미합니다. 다시 말해 하나의 소스코드를 어떤 컴파일러로 컴파일하더라도 동일한 목적 코드가 생성됩니다.

Unspecified Behavior

하나의 결정자에 두 개 이상의 종속자가 대응되는 성질을 모호성이라고 부릅니다. 그리고 모호성이 있는 행동을 지정되지 않은 행동이라고 부릅니다. 동일한 입력 값에 대해 출력 값이 유일하지 않을 수 있다는 의미입니다.

프로그래밍 언어에서 지정되지 않은 행동은 어떠한 Statement가 컴파일러에 따라 다른 목적 코드를 생성할 수 있음을 의미합니다. 이런 상황은 해당 Statement를 어떤 목적 코드로 generate할 것인지 Document에 명시되어있지 않기 때문에 발생할 수 있습니다.

Undefined Behavior

입력값이 정의역의 원소가 아닐 때 출력값은 정의되지 않은 행동입니다. 만약 정의역을 Integer로 정의한 함수 F에 1.5라는 값이 입력되었다면 함수가 반환하는 출력 값은 정의되지 않은 행동입니다.

위와 같이 정의역의 원소가 아닌 값이 입력되었을 때 반환되는 값은 치역의 원소가 아닐 수도, 우연히 치역의 값일 수도 있습니다. 어떤 값이 나올지 예측할 수 없습니다.

정의역의 원소가 단순히 수치적 값이 아니라 어떠한 상황이나 행동일 수도 있습니다. 가장 대표적인 정의되지 않은 행동이 바로 널포인터를 역참조하는 행동입니다. 후술하겠지만 정의되지 않은 행동은 예외로 이어질 가능성이 높아 고급 언어에서는 정의되지 않은 행동으로 유래될 수 있는 예외 클래스를 정의하는 경우가 많습니다.

지정되지 않은 행동과 정의되지 않은 행동의 차이점이 궁금하신 분도 계실 것 같습니다. 전자의 경우에는 정의역의 결정자가 치역의 종속자에 대응하지만 2개 이상의 종속자에 대응하는 경우이고 후자는 애초에 결정자가 정의역의 원소가 아닌 경우입니다.

Exception

입력값이 정의역의 원소이지만 유일한 출력값을 반환할 수 없는 상황을 예외라고 부릅니다. 예외의 원인에는 하드웨어의 자원 부족, 정의되지 않은 행동 등이 있습니다.