1. Static Scoping (정적 스코핑)
Statically scoped (정적 스코프) = lexically scoped
: Compile 시점에 스코프가 확정되어 Code를 보고 알 수 있다.
ex. C, Jaca, Python, C# ...
2. C언어에서의 Scope
C 언어는 정적 스코프(lexical scope)를 따른다.
- 함수에 진입하면 새로운 스코프가 생성되며.
함수 내에서 선언된 지역 변수나 객체에 대한 바인딩이 스코프 내에서 생성된다.
- 함수 내에서 선언된 지역 변수가 전역 스코프에 이미 있는 변수와 이름이 충돌하면,
지역 변수가 전역 변수를 숨긴다.
- 함수가 종료될 때(서브루틴에서 반환할 때) 지역 스코프가 파기되며,
그 스코프 내에서 선언된 지역 변수 또는 객체의 바인딩도 파기됩니다.
- 함수 종료 후 숨겨졌던 전역 변수가 다시 활성화됩니다.
* subroutine을 돌 때, Scope 내에서는 전역 변수 a를 알 수 없다.
3. Static Scoping (정적 스코핑)
- 이름 ~ 객체 간의 바인딩 결정 at Compile time
- 실행 시점 고려 x, Code Text만 보고 알 수 있다.
- 주로, 프로그램의 특정 지점을 둘러싸는 블록 내에서 가장 가까운 선언에서 이름에 대한 "현재" 바인딩(연결)을 찾는다.
int n = 4;
int f() {
int n = 3;
n = ~ ; # 어떤 n을 가져올까?
}
위에서 n을 사용할 때, 블록 내에서 가장 가까운 선언을 찾으면 된다. ( n = 3 )
4. 정적 스코핑의 발전
4-1. Basic (초기 버전)
- 지역, 전역의 개념 없이 Global Scope 하나 존재.
- 변수의 명시적 선언 x (python과 같이), 사용하면 동시에 선언됨.
a = 4 // declare 된 것
4-2. 초기 Fortran 90 초기
- 지역, 전역 구분 시작
- 변수의 명시적 선언은 선택 사항
(선언 안 하면 현재 함수의 지역변수라고 가정)
- 지역 변수의 수명은 서브루틴의 단일 실행까지 ( 즉, 재귀 사용 불가)
(이전 포스팅에서 Fortran 90 부터 재귀라는 개념이 탄생했다고 이야기함)
- 서브루틴 내부에서 변수를 선언하면 그 변수의 수명은 해당 서브루틴이 실행되는 동안으로 제한된다.
- 즉, 서브루틴이 호출될 때마다 변수가 생성되고, 서브루틴 실행이 끝나면 변수가 파괴된다는 의미
🤔 함수 실행이 끝나도 사라지지 않게 하고 싶으면??
5. Save 키워드
-> "save" 키워드 사용 ( = C의 static, Algol의 own과 비슷하다.)
-> object의 life cycle이 전역변수와 동일하게 흘러간다.
🚨 bindign의 life cycle X.
서브루틴이 실행 중이지 않을 때는 해당 변수의 이름과 변수 바인딩은 비활성화
# scope 1
{ static n ~ ; }
# scope 2
{ n = ~ ; } // 위의 n의 life cylcle, alive
binding은 위 서브루틴이 끝났을 때 끊어졌지만, n 이라는 객체의 life cycle은 static 으로 인해 살아있다.
고로 scope 2 에서도 위의 n이 사용 가능하다.
(ex. scope 2에서 값을 더 했다면, 다른 scope에서 더한 값이 그대로 유지된 채 사용된다.)