인프런 커뮤니티 질문&답변

조준수님의 프로필 이미지
조준수

작성한 질문수

홍정모의 따라하며 배우는 C언어

2.9 함수 만들기

프로토타이핑에 관한 질문입니다

작성

·

207

0

강의에서 void로 선언된 함수의 경우 main함수 뒤에 선언할 경우에 제일 앞부분에 선언해야 에러가 뜨지 않는다는것을 알았는데요.

int로 선언된 함수의 경우 void로 선언한 함수와 다르게 앞부분에도 선언을 안해도 에러없이 출력이 됩니다. 혹시 왜이런건지 알수 있을까요? ( int 뿐만아니라 float, long 일때도 마찬가지로 오류없이 컴파일되네요)

그리고 다른언어(C#,JAVA) 같은경우에는 void함수를 선언할때 main 함수 뒤에 선언하고 굳이 앞부분에 프로토타이핑을 안해도 자동으로 함수를 불러오던데, 이건 각 언어만의 특징이라 그런건지 아니면 C언어로부터 개선되서 이렇게 가능하게 된건지 알고싶습니다. 질문이 많네요 ㅠㅠ

답변 2

2

안녕하세요 :)

1)

컴파일러는 모르는 함수를 만나면 일단 int 를 반환하는 함수겠거니 하고, 그 모르는 함수를 int 를 반환하는 함수를 정의하고 넘어갑니다. int 가 자료형 중에 가장 기본이 되는 자료형이기 때문인듯 합니다. 

main 함수를 컴파일 할 시점엔 test 와  test2 를 보고 얘 누구지? 하게 되는건데 test와 test2 가 int 를 반환하는 함수라고 일단 정의 내리고는 넘어간거에요! C4013 경고를 보시면 int 형으로 반환하는 함수로 간주하겠다는 메세지가 출력된 것을 볼 수 있습니다. 그러고 아래로 내려와서 진짜 test, test2 정의를 마주했을 땐 진짜 int 를 반환하는 함수가 맞았기 때문에 별탈 없이 실행이 되었던 것입니다.

이건 test 와 test2 함수를 long 을 반환하는 타입의 함수로 정의했을 때의 경고 출력 모습입니다. main 함수를 컴파일 할 시점엔 test, test2 함수가 누군지 모르기에 일단 int 를 반환하는 함수겠거니 하고 넘어간 것을 알 수 있습니다. 그런데 막상 main 함수 컴파일 후 내려와서 확인해보니 test 와 test2 는 long 을 반환하는 함수였던거에요! 그래서 C412 경고 메세지를 보시면, 형식이 다시 재정의 되었지만 심각하지는 않다고 말하고 있습니다. test, test2 정의를 보고 long 으로 반환하는 함수로 int 에서 long 으로 다시 재정의 해주었다는 것을 확인할 수 있습니다. (int 와 long 은 서로 형변환이 가능한 형태이기에 이게 가능한것이 아닌가 하고 추측해봅니다.. float도 마찬가지구요!)

반면 test, test2 가 void 로 리턴타입이 없는 함수로 정의되어있을 땐 이렇게 컴파일 에러가 발생합니다. 그 이유는, test, test2 함수 얘네가 누군지 모르니까 일단 int 반환 함수로 정의해두고 내려왓는데 막상 내려오니 void 였던 것입니다. int 반환 함수로 정의했다가 long 반환 함수 정의로 바꾸는건 되지만 int 반환 함수로 정의했는데 아무것도 반환하지 않는 함수로 바꾸는건 안되나봅니다.. ㅎㅎ.. 그래서 에러가 발생한 것 같아요! void 함수는 꼭 전방 선언 해주는게 좋을 것 같아요. 

2) 

C에서 개선하고자 그런 형태가 된건진 잘 모르겠지만 이건 각 언어만의 특징인 것 같아요. C와 C++ 은  마치 사람이 읽는 방식대로 컴파일러가 위에서부터 읽어 내려와서 그런지 선언 문 작성하는 순서가 매우 중요하지만, C# 과 Java 는 질문자님 말씀처럼 전혀 상관이 없더라구요. 

https://stackoverflow.com/questions/2632601/why-are-forward-declarations-necessary 

위 링크를 한번 참고해보시면 좋을 것 같아요. c#, java 와 비교하여 질문한 글이네요!

0

조준수님의 프로필 이미지
조준수
질문자

어우 정말 정성스러운 답변 감사합니다;;; 궁금증이 너무나도 잘 해결되었습니다

조준수님의 프로필 이미지
조준수

작성한 질문수

질문하기