미정의 값은 컴퓨팅, 특히 프로그래밍 분야에서 사용되는 개념으로, 문법적으로는 유효함에도 불구하고 식(expression)이 언어에서 의미상 올바른 값을 가지고 있지 않은 상태를 가리킨다. 이 개념은 실제로 널리 인정된 컴퓨터 과학 용어로서, 위키백과 등 공신력 있는 백과사전에 별도의 표제어로 수록되어 있다.
정의와 구별
미정의 값은 빈 문자열, 불리언(Boolean)의 "false", 또는 정의되었으나 비어 있는 값과는 구별된다. 예를 들어 값이 "없음"을 명시적으로 나타내는 null이나 빈 값은 그것 자체로 하나의 정의된 값이므로 미정의 값과 같은 범주에 속하지 않는다. 미정의 값은 식이 결과적으로 산출할 올바른 값이 존재하지 않는 상태를 의미한다.
발생과 처리 방식
상황에 따라 미정의 값을 평가하려는 시도는 예외(exception) 또는 미정의 동작(undefined behaviour)을 일으킬 수 있다. 그러나 일부 프로그래밍 언어에서는 미정의 값이 정상적이고 예측 가능한 프로그램 실행 중에도 발생할 수 있다.
동적 자료형 언어들은 일반적으로 미정의 값을 가능하면 명시적으로 처리한다. 예를 들어 펄(Perl)은 undef 연산자를 통해 미정의 값을 변수에 할당할 수 있게 한다. 다른 형 체계에서 미정의 값은 알 수 없고 예측하지 못하는 값을 의미할 수 있으며, 평가 시도 시 프로그램 실패를 일으킬 수 있다.
미정의 값의 구체적 사례
부분 함수(partial function)의 값은 그 인자가 정의역 밖에 있을 때 미정의 상태가 된다. 대표적인 사례로는 다음과 같은 것들이 있다.
- 0으로 나누기
- 음수의 제곱근 또는 로그 계산
- 배열의 인덱스가 범위를 벗어난 접근
- 연관 배열에서 존재하지 않는 키에 대한 접근
처리 방식의 유형
미정의 값을 실제 프로그램에서 처리하는 방식은 크게 세 가지로 나뉜다.
예약 값(reserved value): 미정의 상태를 나타내기 위해 별도의 특수 값(null 등)을 마련하는 방식이다. C 표준 입출력 라이브러리의 EOF, IEEE 754 부동소수점 표준의 NaN, SQL의 NULL 등이 대표적인 예이다. 펄 언어는 defined() 술어를 통해 식의 정의 여부를 검사할 수 있게 한다.
예외 처리(exception handling): 함수가 정상적으로 값을 반환하지 못하는 경우 예외 체계를 이용하여 실패를 알리는 방식이다. 이 경우 값을 반환하는 대신 예외를 발생시키므로 별도의 특수 값을 발명할 필요가 없다.
미정의 동작(undefined behaviour): 미정의 여부를 감지하지 않고 호출자에게 책임을 전가하는 방식이다. C 언어의 댕글링 포인터 역참조가 대표적인 예로, 포인터의 유효성을 검증하지 않고 역참조를 수행함으로써 속도를 얻는 대신 안전성을 희생한다.
엄밀한 의미의 미정의 값
엄밀한 정의에 따르면, 미정의 값은 표면적으로 유효한(비-null) 출력이지만 의미가 없으며 미정의 동작을 유발하지 않는 값을 의미한다. 예를 들어 C 라이브러리의 strftime 함수에서 출력 버퍼가 결과를 담기에 충분히 크지 않은 경우 오류가 반환되고 버퍼의 내용은 미정의 상태가 된다. 또한 하드웨어에서 정보를 전달하지 않는 배선도 실제로는 어떤 전압 수준을 가지는 것과 유사한 상황이 소프트웨어에서도 발생할 수 있다.
때로는 미정의 값이 제한된 방식으로 유용하게 활용되기도 한다. C 언어에서 포인터를 정수로 변환할 때 그 수치 값은 미정의이지만, 디버깅이나 두 포인터의 동등성 비교, XOR 연결 리스트 생성 등에 사용될 수 있다. 낙관적 동시성 제어 시스템에서도 경쟁 상태를 감지하기 전에 읽힌 미정의 데이터를 버리고 재시도하는 방식으로 안전하게 처리된다.
표기법
계산 가능성 이론에서 식의 미정의성은 expr↑로, 정의성은 expr↓로 표기한다.
관련 개념
- 정의된 값과 미정의 값(수학)
- SQL의 NULL
- 타입 이론
- 유닛 타입(unit type)