C & C++/개념(Concept)

C/C++ 개념: 전방 선언(forward declaration)

kim선달 2020. 11. 12. 00:22
Select Language

전방 선언(forward declaration)


1. 설명

함수나, 구조체, 열거자, 공용자, 외부(extern) 변수 (C++ 에서는 클래스도) 등을 그 실제 구현(implementation) 시점보다 앞서서 선언(declare)만 하는 것을 말합니다.

물론, 구현부와 선언부의 서명(signature)은 일치해야 합니다.

 

서로를 호출하는 함수, 외부(extern) 변수, PImple 기법 등에서 사용됩니다.

헤더와 소스 파일로 구현부, 선언부를 분리하는 행위는 기본적으로 모두 전방 선언에 속합니다.

 

※ main 함수보다 아래에서 구현된 함수를 호출할 때도 main 위에서 해당 함수를 전방 선언해야 합니다.

하지만 이런 케이스는 그냥 해당 함수를 main 위로 옮기면 되는 거라(원래는 다른 헤더 파일로 옮기는게 더 맞겠죠) 전방 선언은 굳이 필요 없습니다.

 

※C++20 에서는 전방 선언 하지 않은 함수를 바로 호출할 수 있습니다. 드디어...


2. 예시

 

#include <stdio.h>

void funcA(int x){
  if (x < 0) return;
  printf("%d from A\n", x);
  funcB(--x);
}

void funcB(int x){
  printf("%d from B\n", x);
  funcA(--x);
}

int main(){
  funcA(3);

  return 0;
}

 

컴파일 해 보면, 다음과 같이 선언되지 않은 식별자 funcB 를 사용했다는 에러 메세지가 나옵니다.

/Users/yonggyulee/CLionProjects/playground/main.cpp:6:3: error: use of undeclared identifier 'funcB'; did you mean 'funcA'?
  funcB(--x);
  ^~~~~
  funcA

 

funcA가 funcB를, funcB도 funcA를 호출하고 있기 때문에, 단순히 이들의 위치만 바꾼다고 해서 해결 될 문제가 아닙니다.

funcA의 시점에서 funcB가 보이지 않는게 문제이므로 funcB만 전방 선언 해 주면 됩니다.

 

#include <stdio.h>

void funcB(int x);
// void funcB(int); 전방 선언은 변수 명을 적지 않아도 됩니다(선택사항)

void funcA(int x){
  if (x < 0) return;
  printf("%d from A\n", x);
  funcB(--x);
}

void funcB(int x){
  printf("%d from B\n", x);
  funcA(--x);
}

int main(){
  funcA(3);

  return 0;
}

예시에서 처럼 리턴 타입, 함수 이름, 매개 변수 타입순서를 동일하게 작성해야 합니다.

매개변수의 이름은 굳이 같을 필요 없고, 이름이 아예 없어도 됩니다.

 

 

결과는

3 from A
2 from B
1 from A
0 from B

 


같이 보면 좋은 글

 

C/C++ 개념: 선언과 구현

C개념: 외부(extern) 변수