강의

멘토링

로드맵

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

egcomkh21님의 프로필 이미지
egcomkh21

작성한 질문수

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

cpp파일 include 관련 질문

작성

·

219

1

안녕하세요. 아래의 main.cpp 파일을 실행시킬 때 doSomething()함수가 differentSource.cpp 파일에서 정의 되어있어 헤더파일의 개념처럼 differentSource.cpp를 main.cpp파일에서 include를 했습니다.

그런데 링크 에러가 나더라구요. main.cpp 파일엔 doSomething의 정의가 되어있지 않기 때문에 함수 중복 정의도 아닌 것이 아닌가요? 에러의 이유가 궁금합니다!

 

<main.cpp 파일>
#include <iostream>
#include "diffrentSource.cpp"

using namespace std;

#define LIKE_APPLE // 매크로

int main()
{
	doSomething();

	return 0;
}



<diffrentSource.cpp 파일>
#include <iostream>
using namespace std;

void doSomething()
{
#ifdef LIKE_APPLE
	cout << "Apple" << endl;

#endif

#ifndef LIKE_APPLE
	cout << "Orange" << endl;

#endif

}

답변 1

1

안녕하세요? 질문&답변 도우미 Soobak 입니다.

 

main.cpp 파일 안에서 .cpp 파일인 differentSource.cpp 파일을 #include 지시문을 통해 직접 포함시키고 있기 때문입니다.

 

#include "differentSource.cpp" 구문은 해당 파일의 내용을 main.cpp 에 그대로 복사하는 것과 같은 역할을 수행합니다.

따라서, 전처리 후에는 사실상 main.cpp 파일 안에 differentSource.cpp 의 내용이 포함된 다음과 같은 상태가 됩니다.

<main.cpp 파일>
#include <iostream>

// differentSource.cpp 의 내용
#include <iostream>
using namespace std;

void doSomething()
{
#ifdef LIKE_APPLE
	cout << "Apple" << endl;

#endif

#ifndef LIKE_APPLE
	cout << "Orange" << endl;

#endif

}
//

using namespace std;

#define LIKE_APPLE // 매크로

int main()
{
	doSomething();

	return 0;
}

 

이렇게 전처리된 main.cpp 파일에 대해서 컴파일을 통해 하나의 목적 파일 main.o 을 생성하고,
differentSource.cpp 파일에 대해서도 컴파일 과정을 통해 differentSource.o 목적 파일을 생성하게 되면,
doSomething 함수는 main.o 파일에도, differentSource.o 파일에도 정의되어 있게 됩니다.

즉, 동일한 함수가 여러번 정의되어 있어 링킹 에러가 발생하게 됩니다.

 

따라서, 함수의 선언과 정의부에 대하여 헤더 파일과 소스 파일에 분리시켜 작성하신 후,
main.cpp 파일에서 헤더 파일을 포함시켜 컴파일을 하시는 것이 보다 좋은 방법입니다.

egcomkh21님의 프로필 이미지
egcomkh21
질문자

안녕하세요! 정성스러운 답변 덕분에 잘 이해하였습니다. 그런데 궁금한 점이 하나 발생하여 추가 질문 드립니다.

main.cpp의 올바른 코드는 아래와 같던데, 그럼 compile을 한다면 main.cpp와 differentSource.cpp가 동시에 compile되고 따라서 void doSomething()을 foward declaration만 해주어도 main cpp에서 function call이 작동한다고 보면 될까요?

 

<main.cpp>
#include <iostream>

using namespace std;
void doSomething();
#define LIKE_APPLE // 매크로

int main()
{
	doSomething();

	return 0;
}

네, 맞습니다!

main.cpp 파일에서 void doSomthing(); 와 같이 전방 선언을 해주면,
main.cpp 파일을 컴파일 할 때, 컴파일러는 doSomething() 이라는 함수가 나중에 정의될 것이라고 이해한 후, doSomting() 함수의 정의 내용에 대해 모르더라도 doSomething() 이라는 함수가 호출될 수 있음을 알게 됩니다.

이후, 링킹 단계를 거치면서 differentSource.odoSomthing() 함수에 대한 실제 정의를 링크하여 최종 실행 파일을 생성합니다.

위 과정을 통해 main.cpp 에서 doSomthing() 함수를 호출할 수 있게 됩니다.

egcomkh21님의 프로필 이미지
egcomkh21

작성한 질문수

질문하기