모던C – 추상상태기계

값과 데이터

C프로그램은 표현방식(representation)보다는 값(value)을 중심으로 처리한다.

특정한 값에 대한 표현은 크게 중요하지 않은 경우가 많다. 값과 표현 사이의 변환 관계는 컴파일러가 처리한다.

표현에 얽매이는 경우 오류가 발생할 가능성도 배제할 수 없다.

예를들면, 8비트 정수로 -1을 표현한다고 생각했을 때 1111 1111이라는 표현을 생각할 수 있지만, 모든 머신이 2의 보수 방식을 이용해서 값을 나타낸다고 할 수 있을까? 또는 바이너리 머신이 아니라 추후에 개발될 수 있는 양자컴퓨터가 사용하는 큐비트에서도 동일한 표현으로 처리할까?

또한 동일한 표현이 서로 다른 값을 나타낼 수 있다. 1111 1111은 255인가 혹은 -1인가?

따라서 특정 머신, 구현에 얽매이지 않기 위해 C에서 데이터의 처리는 값으로 처리해야한다.

추상 상태 기계

C프로그램은 값을 처리하는 기계라고 볼 수 있다. 프로그램에서 사용하는 변수는 실행시점마다 특정한 값을 가지는데, 이 값은 최종 표현식으로 이어지는 중간값일 수 있다.

double x = 5.0;
double y = 3.0;
// ... 
x = (x * 1.5) - y;
printf("x is %g\n", x);

x의 값은 프로그램 실행 시점에 따라 5.0 -> 4.5로 변화한다.

프로그램에서 연산의 수행 과정과 결과가 항상 관측 가능(observable)한 것은 아니다.

주소기반메모리(addressable memory)에 저장하거나 출력 장치에 쓸 때만 볼 수 있다.

중간 계산 과정 중 (x*1.5)의 결과인 7.5를 관측할 수 있는가?

이러한 관측 불가능한 값에 대해서 컴파일러는 최적화(optimization)을 수행할 수도 있다.

컴파일러는 최종 결과의 정확성을 해치지 않는다면 겉으로 드러나지 않는 계산 과정을 얼마든지 축약할 수 있다.

즉, 위의 프로그램을 아래처럼 바꾼다면 프로그램의 동작에 차이가 있는가?

printf("x is 4.5\n");
double x = 4.5;
double y = 3.0;

이 계산 이후로 x, y를 더이상 사용하지 않는다면 어떨까? 다음과 같이 프로그램을 변경한다면 프로그램의 동작에 이상이 생길까?

printf("4.5\n");

이렇게 최적화를 한다고 해도 프로그램은 여전히 동작할 것이며, 프로그래머가 원했던 동작을 정확히 수행할 것이다.

오류없이 최적화할 때 중요한 단 한 가지 사항은, C컴파일러가 관측 가능한 상태(observable state)를 재현하는 실행 파일을 만들어내는지 여부다.

즉, 최적화 이전의 관측 가능한 상태(몇 가지 변수 및 프로그램 실행 중 출력되는 내용)가 동일하게 재현되는 변경이라면, 컴파일러는 자유롭게 최적화를 수행할 수 있다.

또한 이런 관측가능한 상태가 변경되는 전반적인 매커니즘을 추상 상태 기계(abstract state machine)이라고 부른다.

이때 “추상”이라는 용어가 의미하는 것처럼, C언어는 프로그램이 표현하는 추상 상태 기계를 다양한 플랫폼에서 각자의 능력과 필요에 맞게 구현할 수 있는 매커니즘을 제공한다.

추상 상태 기계에 대해 더 자세하게 살펴보기 위해 값, 타입, 표현에 대해 알아야 한다.

값value

C에서 값은 프로그램의 구체적인 구현 방식이나 프로그램 실행중에 표현되는 방식과는 독립적인 추상적인 개체다. 즉 0이라는 값은 모든 플랫폼에서 동일한 효과를 내야한다.(실제 세부적인 구현이 어떻게 되었든, 0을 다른 값x에 더하는 경우 프로그래머는 결과가 x일 것으로 기대할 것이다.)

C의 핵심 속성 중 하나는 이것이다. 값은 모두 숫자이거나 숫자로 변환된다.

타입type

타입은 값에 적용되는 속성이다.

값에는 타입이 있으며 컴파일타임에 결정된다.

값에 적용할 수 있는 연산은 타입에 의해 결정된다.

값의 타입에 따라 연산의 결과가 달라진다.

나중에 더 입력하는 것으로… 졸림…