10장 부 프로그램 (Subprogram)
10.1 개요
부 프로그램 (Subprogram, Procedure)
- 일련의 행위나 계산을 추상화하는 기법으로 제공함
- 실행과 분리해서 선언할 수 있는 블록임 (호출을 요구함)
- 함수(Function): 함수 이름으로 값을 반환하게 할 수 있음
- 서브루틴(Subroutine), 프로시저(Procedure): 매개변수로 값을 반환하게 할 수 있음
부 프로그램의 일반적 특성
- 각 프로시저는 단일 진입점을 가짐
- 호출 프로그램(Caller)은 피호출 프로그램(Callee)의 실행 동안 중단됨
- 부 프로그램 종료 시, 제어는 호출자에게 되돌아 감
프로시저의 구성
- 프로시저 이름
- 매개변수 리스트
- 환경 (Environment; 선언부를 의미)
- 몸체 (Body)
매개변수 결합 (Parameter Association)
1. 위치 매개변수 결합 (Positional Parameter Association)
- 리스트에 나타난 위치로 바인딩 됨
- 짧은 매개변수 리스트에 적합함
2. 이름 매개변수 결합 (Named Parameter Association)
- 이름으로 바인딩 됨
- 매개변수 리스트가 길 때 적합함
- 일부 매개변수 값을 Default로 줄 때 적합함
함수 (Function)
- 함수 이름으로 값을 반환받을 수 있음
- 환경 변화 없이, 함수의 Referential Transparency(참조 투명성) 제공
* Referential Transparency(참조 투명성) : 식의 평가는 값만을 생성하며, 환경을 변경하지 않는 성질을 의미한다.
- 함수 이름에 값을 배정하거나, return 문을 통해 함수 값을 반환함
ex) PL별 함수 반환 값으로 허용되는 데이터 형
Fortran, Algol 60: 스칼라 형
Pascal: 스칼라형, 포인터
PL/I: 스칼라형, 포인터, 문자열
Ada: 모든 데이터 형 (Type과 Parameter Return 사이의 직교성을 제공함)
C/C++: 스칼라형, 포인터 (배열 반환 불가로 인해, 반환문의 직교성을 확실히 제공하지는 못함)
프로시저에서 사용하는 식별자
- 형식 매개 변수
- 지역 변수
- 비지역 변수
프로시저에 관한 고려 사항
- 비지역 변수 값을 바인딩하는 환경은?
- 실 매개 변수의 평가방법은?
- 형식 매개 변수와 실 매개 변수의 바인딩 방법은?
10.2 매개변수 평가와 전달 기법
형식 매개변수와 실 매개변수
실 매개변수
- 호출 프로그램으로 전달하기 위해 사용된 식 또는 이름
형식 매개변수
- 부프로그램이 실행될 때, 실 매개변수를 대신하여 사용하는 이름
- 일반적으로 지역 변수임 (또는 상수 역할을 함)
- 매개변수 명세를 제공 (형식 매개변수 이름, 데이터 형, 바인딩 방법 등)
참조 호출 (Call by Reference, - by Address, - by Location)
- 실 매개변수 값 대신, 주소를 대응되는 형식 매개변수에 보내는 방법
- Caller는 실 매개변수의 주솟값을 계산하여 Callee에게 전달함
값 호출 (Call by Value)
- 형식 매개변수의 지역 변수화(Local-Variable)
- 실 매개변수 값을 대응 지역변수로 복사
- 실 매개변수 값이 불변함
- Caller는 실 매개변수의 주소(또는 값)를 전달함
- Callee는 R-Value를 형식 매개변수의 기억 장소에 복사함
- 이후 다른 지역 변수와 동일하게 취급함
결과 호출 기법 (Call by Result)
- Callee가 리턴 직전에 형식 매개변수의 값을 대응되는 실 매개변수에 복사 후 리턴함
- 형식 매개변수를 지역 변수로 간주함
- 형식 매개변수의 초깃값은 미정의됨 (Callee에서 정의됨)
값-결과 호출 기법 (Call By Value-Result)
- 값 호출 기법과 결과 호출 기법을 함께 사용한 방법
- Callee 실행 시작에 값 호출 기법을 적용함
- Callee 실행 끝에 결과 호출 기법을 적용함
이름 호출 기법 (Call by Name)
- 위 예시처럼, 형식 매개변수와 실 매개변수의 이름이 같아 엉키는 것을 방지하기 위한 방법임
- 형식 매개변수의 이름이 사용될 때마다 그에 대응되는 실 매개변수 자체가 사용된 것으로 간주함
(필요한 R-Value 또는 L-Value를 매번 계산함)
- Caller가 실 매개변수의 R-Value와 L-Value를 계산하여 계산 Routine(THUNK)에 작성함
- Callee가 필요 시, THUNK를 이용하여 필요한 값(R-Value, L-Value)을 계산함
- Caller의 코드가 Callee에 복사되어 나오는 것과 비슷함
- THUNK의 구현이 난해하고, 프로그램 판독성이 난해해 짐
- X대신 J가 위치하고, Y대신 N(J)가 위치함
- 본래 의도는 J값(3)과 N(J)값(N(3))을 바꾸려는 것이었으나, J값(3)과 N(1)값을 바꾸게 되었음
- Call by Value의 경우, B의 값 = 2
- Call by Name의 경우, B의 값 = 4 (A(2))
- Call by Reference의 경우, B의 값 = 3 (A(I))
10.3 형식 매개변수 명세
- 실 매개변수와 형식 매개변수의 정적 형 검사는 형식 매개변수의 명세표를 요구함
- 형식 매개변수의 명세: 데이터형, 전달 기법, 초기값, 대응 관계 등
ex) PL들의 형식 매개변수 명세
Pascal: 데이터형, 전달 기법 (값 전달 기본, var 선언 - 참조 전달, 값 - 결과 전달)
Algol 60: 전달 기법 (이름전달 기본, value 선언 - 값 전달)
Ada: 전달 기법 - 예약어 in (값 전달), out (결과 전달), in out (값-결과 전달)로 전달 방법 선택
in - 지역 상수 취급 (지역 변수 취급하지 않음)
형식 매개 변수의 데이터 형 선언
형식 매개 변수의 디폴트(초기)값 선언 가능 (지역 상수인 in mode도 가능)
Ada 함수는 투명성을 위해 in 모드만 가능
10.4 부수효과와 이명 (Side Effect, Aliasing)
부수 효과 (Side Effect)
- 단위 프로그램 간 의사 소통 방법 (비지역 변수 접근, 비지역 변수 값을 수정하면 부수 효과가 발생)
- 참조 전달 기법, 이름 전달 기법 (실 매개변수 값이 바뀌는 부수 효과가 생겨 심각한 오류를 발생)
- 프로그램 판독성 저하, 심각한 오류 발생, 함수의 투명성 상실
이명 (Aliasing)
- 동일한 기억 장소를 함께 사용하는 다른 이름(포인터)
- 한 변수 값이 변하면 동일 장소를 사용하는 다른 변수의 값도 변화하는 이명 효과가 발생함
- 초기 PL들에서는 효율적인 메모리 사용을 위해 이명을 허용했음
ex) Fortran의 EQUIVALENCE, Cobol의 REDEFINES, C의 union 등
* 그림 10.4는 간접적인 이명에 대한 그림임
10.5 연산자 중복 정의
중복 정의 연산자를 결정하기 위한 방법
- 데이터 형 정보를 파스 트리의 각 노드에 붙인 것을 가정함 (컴파일러가 동적 또는 정적으로 결정)
- 트리의 단 노드들의 데이터 형 확정 (단 노드의 데이터 형 결정)