-
선언 순서
객체 X가 블록 B의 어딘가에서 선언되었다고 가정하자.
X의 범위는 B의 선언 전 부분도 포함될까??
또한 그 부분에서 X가 사용될 수 있을까??
즉, 코드상 수식A에서는 속한 현재 범위에서 선언된 모든 이름을 참조할 수 있을까 아니면 범위의 A앞에서 선언된 이름만 참조할 수 있을까?초기 언어들은 범위 제일 앞에 선언이 나와야 했다.
C는 이름에 대해 선언 후 사용의 원칙을 가지는데, C++과 자바는 사용전 선언의 요구를 많은 경우에 지키지 않아도 되도록 규칙을 더욱 완화시켰다. 클래스의 메소드 내부에서는 뒤에 나오는 선언의 멤버를 볼 수 있다. 그러나 지역변수는 자바에서도 선언 후 사용해야 한다.
선언과 정의
선언
- 이름과 범위를 표시하는 역할
- 세부적은 정보가 일부 생략될 수 있다.
정의
- 객체의 모든 세부 사항을 명시
재귀 타입이나 재귀 함수 호출은 이름이 사용되기 전에 선언되어야 하는 언어에서는 문제가 생길 수 있다.
C와C++은 이를 해결하기 위해 선언과 정의를 구별한다.
선언은 이름과 범위를 나타내고 구현의 세부사항은 생략될 수 있다.
정의는 이름이 결합되어 있는 대상을 컴파일러가 구현할 수 있을 정도로 충분히 자세하게 기술하는 것이다. 선언이 정의가 될 만큼 충분히 완전하지 않다면 별도의 정의부가 범위 내 어딘가에 있어야 한다.전방선언을 통해 미리 이름(타입, 함수)을 선언
자바는 전방선언을 하지 않는다.C에서는 구조체 manager를 다음과 같이 선언만으로 표시할 수 있다.
struct manager; /* declaration only - 전방선언 */ struct employee { struct manager *boss; struct employee *next_employee; ... }; struct manager { /* definition */ struct employee *first_employee; ..
void list_tail(follow_set fs); /* declaration only */ void list(follow_set fs) { switch (input_token) { case id : match(id); list_tail(fs); ... } void list_tail(follow_set fs) /* definition */ { switch (input_token) { case comma : match(comma); list(fs); ... } }
최초의 manager 선언은 이름만 소개하는 것으로 충분한데 왜나하면 모든 포인터는 동일한 크 기를 가지고 컴파일러는 employee의 구현을 위해 manager의 세부적인 것을 알 필요가 없기 때문 이다. 반면에 list_tail의 전방 선언은 반환형과 매개변수 리스트를 모두 기술해야만 컴파일러가 list에서 그 함수가 올바르게 호출되었는가를 확인할 수 있기 때문이다.
자바는 클래스 내에서는 모든 필드와 메소드 이름이 선언되기 전에 사용가능하므로 이러한 문제가 생기지 않는다.
728x90