강의

멘토링

로드맵

Inflearn brand logo image

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

slpbr님의 프로필 이미지
slpbr

작성한 질문수

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

4.2 전역 변수, 정적 변수, 내부 연결, 외부 연결

46분관한 설명이 이해가 안갑니다

해결된 질문

작성

·

136

·

수정됨

1

일단 서로 주소가 다른다는것은 알겠습니다.

헤더 파일에서 선언과 define 을 했을 경우 각각 cpp 파일에서 주소가 다르게 나왔다..

이지만 my_constants.cpp 에서 define 을 하고 헤더 파일에는 declaration 만 했을경우 서로 같은 주소가 나오는이유를 잘모르겠습니다.

혹시 추가로 설명을 들을수 있을까요?

답변 2

0

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

 

전역 변수는 기본적으로 External linkage를 가지지만, 본 영상의 49:11에서 언급되듯이 const 를 붙이면 Internal linkage가 됩니다. 만약 const 전역 변수에 extern을 사용한다면, const를 붙임으로 인해 Internal로 제한되었던 linkage가 External로 다시 돌아가는 효과를 얻습니다.

 

이때 헤더 파일과 .cpp 파일에서 각각의 extern이 가지는 의미는 아래와 같습니다. (translation unit이란, 컴파일 시 동일한 오브젝트 파일이 되는 파일들의 모음을 뜻합니다)

  • MyConstants.hextern

    • 선언을 한 곳

    • 다른 translation unit에서 상수의 정의를 찾으라는 의미

  • MyConstants.cppextern

    • 정의를 한 곳

    • External linkage를 부여해서 다른 translation unit(MyConstants.h + main.cpp)에서 여기에 있는 상수의 정의에 접근 가능하게끔 하기

 

즉, 복사본이 생성되었던 기존 방법과는 달리 하나의 메모리 위치만이 할당됩니다.

혹시 링킹 과정에 대해 의문이 드신다면, 다시 질문을 이어서 주셔도 됩니다.

 

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

그래도 이해가 잘안가네요... 저의 질문은 왜 해더파일에서 정의를 하면 각각 cpp 파일이 다른 메모리를 사용하는데, cpp 파일에서 정의를 하면 왜 같은 메모리를 공유하는지 이해가 안갑니다.

조금 더 상세하게, 두 가지 경우에 대해 설명드리겠습니다.

먼저 헤더에서 정의를 하는 경우, 파일의 내용은 아래와 같습니다.

// MyConstants.h

#pragma once

namespace Constants {
    const double pi = 3.14;
}

헤더 파일을 #include하는 것은 해당 헤더 파일의 내용을 그대로 복사해와서 집어넣는 것과 동일합니다. 그래서 이 경우에는 MyConstants.h를 포함하는 모든 .cpp 파일에서 pi라는 변수를 각자 정의하여 사용하게 되고, 출력하는 메모리 주소가 달라지게 됩니다.


그 대신에 헤더에서는 선언만 하고, .cpp 파일에 정의를 한 경우입니다.

// MyConstants.h

#pragma once

namespace Constants {
    extern const double pi;
}
// MyConstants.cpp

namespace Constants {
    extern const double pi = 3.14;
}

이렇게 하면, MyConstants.h를 포함하는 모든 .cpp 파일에서는 pi라는 변수를 전방 선언(1.10 선언과 정의의 분리에서 언급)한 것과 같습니다.

그리고 extern으로 명시했기 때문에 다른 translation unit에서 정의를 찾아 이를 참조하는 방식으로 동작하게 되며, pi라는 변수는 복사본 없이 하나의 메모리 공간만 사용하게 됩니다.


이해에 도움이 될까 싶어 간단한 그림을 그려봤습니다. 검은 화살표는 #include를 나타내고, 빨간 화살표는 상수의 정의를 어디서 찾는지를 의미합니다.

Inflearn_01.excalidraw.png.webp

 

혹여나 이해가 잘 되지 않으신다면 언제든지 편하게 질문해 주세요.

 

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

감사합니다 이해가 됬습니다!

 

-1

안녕하세요, 인프런 AI 인턴입니다. slpbr님께서 질문하신 부분에 대해 설명드리겠습니다.

C++에서 extern 키워드는 전역 변수를 선언할 때 다른 파일에서 정의된 변수를 참조할 수 있도록 합니다. 만약 헤더 파일에서 선언과 초기화(define)를 해 버리면, 각 소스 파일이 그 변수의 별개의 복사본을 가지게 되어 주소가 다르게 나오는 것입니다. 이는 값이 각각 파일별로 별도로 존재하기 때문입니다.

반면, my_constants.cpp에서 변수를 정의하고 헤더 파일에서는 단순히 선언(declaration)만 하는 경우에는 모든 파일이 동일한 전역 변수를 참조하게 되어, 동일한 메모리 주소를 공유하게 됩니다. 이는 extern에 의해 변수 정의를 한 번만 하고 여러 곳에서 사용할 수 있게 하는 것과 동일한 원리입니다. 이렇게 하면 프로그램 내에서 일관된 값을 공유하게 됩니다.

관련 질문 URL은 다음과 같습니다:
46:07 variab extern variable 주소관련

이 링크에서 홍정모 강사님의 답변을 참고하실 수 있습니다. 추가적인 영상 자료도 제공되었으니 확인해 보세요: YouTube 링크.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

slpbr님의 프로필 이미지
slpbr

작성한 질문수

질문하기