C 언어에서 함수 원형(프로토타입)을 선언하지 않은 상태에서, 함수의 본문이 해당 함수의 호출문보다 뒤쪽에 위치해 있다면 어떤 일이 발생할까요? 이런 경우 컴파일러는 함수의 반환형을 기본값인 정수(int)로 암묵적으로 간주합니다.
따라서 함수가 int가 아닌 다른 자료형의 값을 반환하도록 정의되어 있다면 컴파일 오류가 발생합니다. 반대로 반환형이 정수라면 프로그램은 정상적으로 동작하지만, 컴파일러 설정에 따라 경고 메시지가 출력될 수 있습니다.
예제 코드 1 — char 반환형의 경우
#include<stdio.h>
main() {
printf("The returned value: %d\n", function);
}
char function() {
return 'T'; // 문자 'T'를 반환
}
출력 결과
[Error] conflicting types for 'function'
[Note] previous implicit declaration of 'function' was here
컴파일러는 함수를 처음 만나는 시점(호출문)에서 function이 정수를 반환하는 함수라고 암묵적으로 선언해 버립니다. 그런데 이후 함수 정의 부분에서 반환형이 char임을 확인하게 되면, 앞선 암묵적 선언과 실제 정의가 서로 충돌한다고 판단하여 위와 같은 'conflicting types'(타입 충돌) 오류를 발생시킵니다.
추가로 알아둘 점
위 예제에는 사실 한 가지 더 짚고 넘어갈 부분이 있습니다. printf의 인자로 function을 괄호 없이 작성했는데, 이렇게 하면 함수가 호출되는 것이 아니라 함수의 시작 주소(포인터)가 전달됩니다. 함수를 실제로 실행하고 그 반환값을 사용하려면 반드시 function()처럼 괄호를 붙여야 합니다.
예제 코드 2 — int 반환형의 경우
그렇다면 반환형이 정수라면 어떻게 될까요? 컴파일러의 암묵적 가정과 실제 정의가 일치하기 때문에 아무 문제 없이 동작합니다.
#include<stdio.h>
main() {
printf("The returned value: %d\n", function());
}
int function() {
return 86; // 정수 값 반환
}
출력 결과
The returned value: 86
마무리 정리
이처럼 함수를 선언하기 전에 호출하면 컴파일러가 반환형을 int로 추측하기 때문에 예상치 못한 오류나 경고가 발생할 수 있습니다. 참고로 구버전 표준(C89/C90)에서는 이러한 암묵적 함수 선언이 허용되었지만, C99 표준부터는 금지되었으며 최신 컴파일러에서는 대부분 오류로 처리합니다.
따라서 안전하고 이식성 좋은 코드를 작성하려면, 소스 파일 상단이나 헤더 파일에 함수 원형을 미리 선언해 두거나, 함수 정의를 호출문보다 앞에 배치하는 것이 좋습니다.