본문 바로가기
Dev Language/C++

함수 원형이 필요한 이유

by 미티치 2016. 12. 5.

함수 원형이 필요한 이유

 

 

함수 원형은 컴파일러에게 함수의 인터페이스를 알려준다. 예를 들어 double cube(double x); 라는 함수 원형이 있고, main 안에서 double volume = cube(side); 로 선언이 되어있을 때,

1)    함수 원형은 cube()가 하나의 double형 매개변수를 가진다는 사실을 컴파일러에게 알려준다. 따라서 프로그램이 cube()에 매개변수를 제공하는 데 실패하면, 컴파일러는 함수 원형에 근거하여 에러를 검출한다.

2)    cube()함수는 계산을 끝냈을 때 리턴 값을 (CPU의 레지스터나 메모리의) 어떤 지정된 위치에 넣는다. 그러면 호출한 함수(여기서는 main)가 그 위치에서 값을 꺼내온다. cube()double형 이라는 사실을 함수 원형이 컴파일러에게 알려 주므로, 컴파일러는 그 위치에서 몇 바이트를 꺼내고 어떻게 처리해야 하는지 알고 있다. 이 정보가 없다면 컴파일러는 일을 할 수 없다.

3)    만약 함수 원형을 제공하는 대신에, 컴파일러가 파일의 내부를 조사하여 그 함수가 어떻게 정의되어 있는지 직접 확인한다면 굉장히 비효율적일 것이다. 왜냐하면 컴파일러가 그 함수를 찾기 위해 파일의 내부를 뒤지는 동안 main()함수의 컴파일을 잠시 보류해야 한다. 더욱 심각한 문제는 그 함수가 그 파일 안에 들어있지 않을 수도 있다는 것이다. C++은 하나의 프로그램을 여러 개의 파일에 분리해 놓을 수 있다. 이 파일들은 독립적으로 컴파일 된 후에 나중에 하나의 프로그램으로 결합될 수 있다. 그와 같은 경우에, main()을 컴파일 할 때 컴파일러가 그 함수의 코드를 찾지 못할 수도 있다. ( 그 함수가 라이브러리 함수일 때도 마찬가지이다. )

4)    함수 원형이 사용자를 위해 하는 일
-
컴파일러가 함수의 리턴 값을 바르게 처리한다.
-
사용자가 정확한 개수의 매개변수를 사용했는지 컴파일러가 검사한다
.
-
사용자가 정확한 데이터 형의 매개변수를 사용했는지 컴파일러가 검사한다. 사용자가 정확한 데이터 형을 사용하지 않았다면, 컴파일러가 정확한 데이터 형으로 변환한다.

5)    double cube(double num); 이라는 함수가 있다고 가정했을 때 만약에 함수 원형을 사용하지 않는 경우에 double z = cube();라고 선언하면 컴파일러는 이것을 통과시킨다. 이 함수가 호출되었을 때 컴파일러는 cube()의 리턴 값이 놓이는 위치를 찾아보고 그곳에 어떤 수가 있든지 간에 그 수를 사용한다. 이것이 C에서 사용하던 방식이다. C에서는 함수 원형의 사용이 선택적이기 때문에 함수 원형이 없는 C프로그램도 여전히 작동한다. 하지만 C++에서는 함수 원형의 사용이 필수이기 때문에 이러한 에러를 범하지 않도록 컴파일러가 사용자를 보호한다.

6)    또한 매개변수의 개수는 맞지만 데이터 형이 불일치 하는 경우, C에서는 매개변수로 int(16비트) 값을 기대하는 함수에 double(64비트) 매개변수를 전달하면 그 함수는 double 형의 64비트 중 앞부분 16비트만 참조해서 그것을 int형 값으로 처리한다. 따라서 이상한 에러가 발생한다. 그러나 C++에서는 잘못된 산술 데이터 형이 전달되면 함수 원형에 정의되어 있는 데이터 형으로 자동 변환시켜 준다. 하지만 발생할 수 있는 모든 에러를 자동 데이터 형 변환이 막아주는 것은 아니다. 값을 바르게 변환할 수 없거나 또는 정수를 구조체나 포인터 형으로 변환하는 일은 하지 않는다.

7)    함수 원형 비교는 컴파일 시에 일어난다. 이것을 정적 데이터 형 검사라 한다. 정적 데이터 형 검사는 실행 시에 잡아내기 어려운 에러들을 컴파일 시에 잡아낸다.

 

 

 

 

헤더 파일에 선언하는 것들

 

- 함수 원형

- #define이나 const를 사용하여 정의하는 기호 상수

- 구조체 선언

- 클래스 선언

- 템플릿 선언

- 인라인 함수

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Dev Language > C++' 카테고리의 다른 글

참조 변수 & 복사 생성자  (1) 2016.12.06
if문과 switch문  (0) 2016.12.06
함수 오버로딩  (0) 2016.12.06
배열과 포인터  (0) 2016.12.05
스택에 저장되는 값 (자료 백업)  (0) 2016.11.29