C와 JS의 함수 선언,호출 차이
C에서 함수를 선언하고 호출하기 위해서는 main함수 위에 함수원형을 먼저 선언해야 한다고 배웠습니다.
왜 그럴까요? js의 함수 선언문과 함수 표현식은 호이스팅에 의해 선언과 호출의 위치가 중요한데, 궁금해지네요.
C언어 - 원형선언이 필요한 경우
#include <stdio.h>
int sum(int a, int b);
int main(){
int s;
s = sum(30, 40);
printf("sum from 30 to 40=%d\n", s);
}
int sum(int a, int b){
int i,s=0;
for (i = a; i <= b; i++){
s = s + i;
}
return s;
}
C언어 - 원형선언이 필요 없는 경우
#include <stdio.h>
int sum(int a, int b){
int i,s=0;
for (i = a; i <= b; i++){
s = s + i;
}
return s;
}
int main(){
int s;
s = sum(30, 40);
printf("sum from 30 to 40=%d\n", s);
}
컴파일러가 위에서부터 컴파일을 하기 시작하는데 함수가 main보다 뒤에서 만들어지는 경우 main을 컴파일할 때
아직 없는 함수를 호출하게 되므로 에러가 발생합니다.
컴파일을 해보면 이런 에러메시지가 발생합니다.
C99에서는 함수의 암시적 선언이 불가하다는 뜻인데 C99이 뭘까요.
C99은 1999년에 발표된 C언어의 표준버전을 의미한다고 하는데 JS의 ES6 이런 느낌인가요..?
https://ko.wikipedia.org/wiki/C99
C99 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. C99는 C 언어의 현대 개정판이자, C 언어 표준의 과거판인 ISO/IEC 9899:1999의 비공식 이름이다.[1] ANSI의 표준화 이후 C 언어 표준이 상대적으로 정적으로 남아 있었
ko.wikipedia.org
C99의 표준에 의해 함수의 암시적 선언은 허용되지 않습니다. 그래서 함수가 호출되기 이전에 선언되거나 원형을 제공해야 합니다.
그래야 main함수에서 함수를 호출할 때 컴파일러가 그 함수의 존재와 시그니처를 알게 되므로 에러가 발생하지 않습니다.
반면에 js에서는 함수를 선언문으로 선언하는 경우에 호이스팅에 의해 함수 선언 전에 호출을 할 수 있습니다.
const result = sum(10, 20);
console.log(result);
function sum(a, b) {
let value = 0;
for (i = a; i <= b; i++) {
value += i;
}
return value;
}
인터프리터 언어인 자바스크립트는 js엔진에 의해 실행되는데 런타임에 들어가기 전에 평가 단계에서 식별자들을 초기화합니다.
변수와 함수선언문의 평가방법은 다르지만 여기서는 함수 선언문의 평가방법만 다루겠습니다.
함수 선언문은 평가 시에 먼저 초기화되는데, 이때 함수의 이름과 동일한 식별자로 초기화됩니다.
그리고 변수와 다르게(var로 선언된 변수는 undefined로 초기화) 함수의 실제 내용으로 초기화됩니다.
그래서 변수의 경우에 런타임에서 선언보다 먼저 참조하게 되면 undefined가 나오거나 TDZ에 빠져서 참조에러가 발생하는 반면 함수 선언문의 경우에는 런타임에 위 코드처럼 이상 없이 함수를 호출하게 됩니다.
그럼 C에서는 모든 함수를 main 위에 선언하고 원형선언을 생략하는 게 편하지 않나 생각할 수 있지만..
함수가 함수를 호출하는 식으로 프로그램이 커지고 복잡해지면 어떤 함수를 어떤 함수보다
더 위에 선언해야 할지 판단하는데 어려움을 겪게 될 것 같습니다.
그래서 main을 기준으로 위에 원형선언을 해주고 아래에 실제 함수 바디를 작성하도록 배우는 것 같습니다!