본문 바로가기
C++/기초

C++ 기초 : 분할 구현의 문제점

글: 시플마 2024. 3. 22.

함수를 선언하는 헤더 파일과

함수를 정의하는 소스 파일,

그리고 함수를 사용하는 파일로 나누었습니다.

 

그러면 '굳이 함수의 선언과 정의를

나누지 않고 헤더 파일에 다 넣으면 안될까?'라는

생각이 듭니다. 하지만 이런 경우 문제가 발생합니다.

 

 

아래 그림처럼

헤더 파일에 Add 함수의 선언과 정의를 모두 넣고

 

다른 파일에서 Add 함수를 사용하려면

각 파일마다 #include를 써야 합니다.

#include는 사실 복사 붙여넣기와 같습니다.

즉 각 파일마다 Func.h의 내용을 복사해서 붙여넣는 것이죠.

그렇게 되면 각 파일마다 Add 함수가 선언되고 정의되는 것입니다.

 

각각의 파일에서는 문제가 발생하지 않을지 몰라도

결국 마지막에 하나의 파일로 합쳐질 때 

Add 함수가 여러 개 선언되고 정의되는 문제가 발생합니다.

(같은 이름의 함수를 여러 개 선언하면 오류가 발생합니다.)

 

 

 

그래서 아래 그림처럼

 

함수의 선언은 헤더 파일에, 

함수의 정의는 소스 파일에 하는 것입니다.

 

#include "Func.h" 덕분에

각 파일에 Add 함수의 선언이 붙여넣기되어

Add 함수를 호출할 수 있게 됩니다.

(함수를 선언만 해놓으면 이름이 같아도 오류가 발생하지 않습니다.)

 

이후 모든 파일을 병합하는 링크 과정에서 

Add 함수가 정의된 Func.cpp 파일을 통해

각 파일에서 호출된 Add 함수가 작동합니다.

 

 


 

 

 

근데 함수를 분할 구현하면

분할 구현한 함수에서 

'전역 변수'를 사용할 수 없다는

문제가 발생합니다.

 

다른 파일에 전역 변수 global을 선언하고

Add 함수가 정의된 Func.cpp에서 

Add 함수에 전역 변수 global에 10을 대입하는 

코드를 넣었습니다.

 

분명 링크 과정 이후 하나의 파일로 병합되면

전역 변수가 들어 있는 메모리의 데이터 영역에는

변수 global이 존재할 것입니다.

 

그러나 전역 변수는 선언한 파일에서만

유효합니다. 즉 Func.cpp 파일에서는 

global이라는 변수가 뭔지 모르기 때문에

오류가 발생하여 링크 과정으로 넘어갈 수조차 없습니다.

 

 

 

그러면 생각해 볼 수 있는 것이,

 

위와 같이 

Add 함수의 선언이 있는 Func.h 파일에 

전역 변수를 선언하는 것이죠.

 

각 cpp 파일에는 include 지시문을 통해

'Func.h'가 붙여넣기되었으니 전역 변수 global을 

사용할 수 있습니다.

 

또한 Add 함수가 정의된 'Func.cpp' 파일에도

include 지시문을 통해 'Func.h'가 붙여넣기되었으니

전역 변수 global의 존재를 인식하므로

전역 변수 global을 사용해도 오류가 발생하지 않죠.

 

하지만 이것도 결과적으로 문제가 있습니다.

 

당장 각 파일에는 문제가 없기 때문에 

링크 과정까지는 넘어갈 것입니다.

 

 

 

그러나 링크 과정에서 

 

위 그림과 같이

각 cpp 파일에는 include 지시문을 통해

'Func.h'가 붙여넣기되었기 때문에

전역 변수로 사용하려던 변수 global이

각 파일마다 붙여넣기되어 여러 개가 되면서

오류가 발생합니다.

 

왼쪽 하단, 오류 목록을 봅시다.

코드는 'LNK2005', 즉 링크 과정에서 발생한 오류이며

int형 변수 global이 이미 정의되어 있다고 나오죠.

 

 

 

실제 파일을 통해 살펴봅시다.

헤더 파일, 소스 파일, 메인 함수가 있는 파일 중

아무거나 우클릭하여 '상위 폴더 열기'를 누르면

 

 

 

 

아래와 같이

해당 프로젝트와 관련된 파일이 나옵니다.

여기서 'x64' - 'Debug' 폴더를 들어가면

 

 

 

 

obj 파일이 나옵니다.

'func.obj'는 Add 함수의 선언과 정의로 이루어진 파일,

즉 func.h + func.cpp의 구성이고

'main.obj'는 main 함수가 있는 main.cpp 파일이죠.

 

func.obj에 전역 변수 global이 선언되어 있으며

main.obj에서 include 지시문을 통해

전역 변수 global이 붙여넣기되었을 것입니다.

 

각 obj 파일은 문제가 없을 것입니다.

그러나 이 obj 파일이 병합되어

하나의 프로그램이 되기 위한 링크 과정에서

func.obj에도, main.obj에도 변수 global이 존재하므로

오류가 발생하는 것입니다.

 

 


 

 

 

이러한 문제를 해결하기 위해 있는 것이

정적 변수(static)와 외부 변수(extern)입니다.

 

두 변수는 완전 다른 종류이며

위와 같은 문제를 해결하려면

외부 변수를 사용해야 합니다.

 

 

 

 

강의 출처 : https://www.youtube.com/watch?v=PFc4g8mxOiI&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&pp=iAQB


 

'C++ > 기초' 카테고리의 다른 글

C++ 기초 : 운영체제  (0) 2024.03.29
C++ 기초 : 정적 변수와 외부 변수  (0) 2024.03.29
C++ 기초 : 분할 구현  (0) 2024.03.06
C++ 기초 : 지역 변수 / 전역 변수  (0) 2024.03.05
C++ 기초 : 구조체  (0) 2024.03.03