int main()과 int main(void), 무엇이 다를까?
C와 C++ 모두에서 프로그램의 시작점은 main 함수입니다. 그런데 이 함수를 선언할 때 int main()처럼 괄호를 비워두는 경우와 int main(void)처럼 명시적으로 void를 적는 경우가 있습니다. 겉보기에는 차이가 없어 보이지만, C와 C++은 이 둘을 서로 다르게 해석합니다.
C 언어에서의 동작
C 언어에서는 함수 선언 시 매개변수 목록을 비워두면 '매개변수가 지정되지 않음(unspecified)'으로 해석됩니다. 따라서 컴파일러는 해당 함수가 어떤 인수든 받아들일 수 있다고 간주하며, 호출 시 여러 개의 인수를 전달해도 컴파일 오류가 발생하지 않습니다.
반면 void를 명시하면 '매개변수가 없음'을 확실하게 선언하는 것이므로, 인수를 전달하려고 하면 컴파일 오류가 발생합니다. 즉, C에서 int main()과 int main(void)는 사실상 같게 동작하지만, int main(void)가 더 안전하고 명확한 방식입니다. 이는 main 함수에 임의의 인수가 전달되는 것을 원천적으로 차단해 주기 때문입니다.
C 예제 코드
아래 코드는 매개변수 없이 선언된 main 함수에 인수를 전달하며 재귀 호출하는 예제입니다.
#include <stdio.h>
int main() {
static int counter = 3;
if (--counter) {
printf("%d ", counter);
main(5); // 인수를 전달했지만 C에서는 컴파일 성공
}
}
실행 결과 (C)
2 1
C 컴파일러는 비어 있는 매개변수 목록을 엄격하게 검사하지 않으므로 main(5) 호출이 허용되며, 프로그램은 정상적으로 실행됩니다.
C++ 언어에서의 동작
C++에서는 상황이 완전히 다릅니다. C++에서 빈 괄호 ()는 곧 (void), 즉 '매개변수 없음'을 의미합니다. 따라서 int main()과 int main(void)는 문법적으로 완전히 동일하며, 매개변수 없이 선언된 함수에 인수를 전달하면 컴파일 오류가 발생합니다.
C++ 예제 코드
#include <iostream>
using namespace std;
int main() {
static int counter = 3;
if (--counter) {
cout << counter << " ";
main(5); // C++에서는 컴파일 오류!
}
}
컴파일 결과 (C++)
main.cpp: In function 'int main()':
main.cpp:10:13: error: too many arguments to function 'int main()'
main(5);
^
main.cpp:5:5: note: declared here
int main()
^~~~
위와 같이 C++ 컴파일러는 '함수에 너무 많은 인수가 전달되었다(too many arguments)'는 오류 메시지를 출력하며 컴파일을 거부합니다.
정리 및 권장 사항
- C 언어:
int main()은 매개변수가 지정되지 않은 것으로 해석되어 인수 전달이 가능하며,int main(void)와 사실상 같게 동작합니다. - C++ 언어:
int main()과int main(void)는 완전히 동일하며, 인수를 전달하면 컴파일 오류가 발생합니다. - 권장: 어떤 언어를 사용하든
int main(void)로 작성하는 것이 의도를 명확히 드러내는 좋은 습관입니다. 참고로 최신 C 표준(C23)부터는 C에서도 빈 괄호가(void)와 동일하게 처리됩니다.
마지막으로 주의할 점은, C++ 표준에서는 main 함수의 재귀 호출이 허용되지 않는다는 점입니다. 위 예제는 개념 설명을 위한 것일 뿐이므로, 실제 프로젝트에서는 이러한 패턴을 피하는 것이 좋습니다.