메모리 모델
메모리 모델 (Memory model)
프로그램이 실제로 메모리를 어떻게 바라보는지, 특히 다중 스레드에서 어떤 의미로 "같은 메모리"를 공유하는지 이해하려면 C++ 추상 머신(abstract machine)이 정의하는 메모리 모델부터 알아야 해요.
출처: cppreference
본문
메모리 모델은 C++ 추상 머신을 위한 컴퓨터 메모리 저장의 의미론(semantics)을 정의해요.
C++ 프로그램이 사용할 수 있는 메모리는 하나 이상의 연속된 바이트(byte) 시퀀스예요. 메모리 안의 각 바이트는 고유한 주소(address)를 가져요.
바이트 (Byte)
바이트는 주소를 지정할 수 있는 최소 메모리 단위예요. 연속된 비트들의 시퀀스로 정의되며, 다음 값들을 담기에 충분히 큰 크기예요:
- 임의의 UTF-8 코드 유닛(256개의 서로 다른 값)의 값, 그리고
- 기본 실행 문자 집합(basic execution character set)에 속한 임의의 원소 (C++23 이전까지는), 기본 리터럴 문자 집합의 임의 원소의 보통 리터럴 인코딩 (C++23부터)
C와 마찬가지로, C++도 8비트 이상 크기의 바이트를 지원해요.
char, unsigned char, signed char 타입은 저장과 값 표현 모두에 정확히 한 바이트를 사용해요. 바이트 안의 비트 수는 CHAR_BIT 또는 std::numeric_limits<unsigned char>::digits로 알 수 있어요.
메모리 위치 (Memory location)
메모리 위치는 비트 필드(bit-field)가 아닌 스칼라 타입 객체의 객체 표현(object representation)이 차지하는 저장 공간, 또는 길이가 0이 아닌 비트 필드들의 가장 긴 연속 시퀀스 중 하나를 말해요.
참고할 점이 하나 있어요. 참조(reference)나 가상 함수 같은 언어의 여러 기능은, 프로그램이 접근할 수는 없지만 구현이 관리하는 추가적인 메모리 위치를 수반할 수 있어요.
메모리 위치가 어떻게 나뉘는지 예시로 봐볼게요.
struct S
{
char a; // 메모리 위치 #1
int b : 5; // 메모리 위치 #2
int c : 11, // 메모리 위치 #2 (계속)
: 0,
d : 8; // 메모리 위치 #3
struct
{
int ee : 8; // 메모리 위치 #4
} e;
} obj; // 객체 "obj"는 4개의 서로 다른 메모리 위치로 구성된다
여기서 주목할 점은, 서로 다른 비트 필드라 해도 그 사이에 0 길이의 비트 필드가 끼어 있지 않고 인접해 있으면 같은 메모리 위치로 취급한다는 거예요. b와 c는 둘 다 메모리 위치 #2에 속해 있죠. 이후 [: 0] 비트 필드가 다음 비트 필드를 다른 위치로 나누고, 그 뒤 d가 메모리 위치 #3이 돼요. 그리고 e는 멤버 객체라서 또 별개의 메모리 위치 #4를 차지해요.
결함 보고 (Defect reports)
다음 동작을 바꾸는 결함 보고(defect reports)가 이전에 발표된 C++ 표준에 소급 적용됐어요.
| DR | 적용 대상 | 발표 당시 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1953 | C++98 | 같은 저장 공간을 차지하는 객체들은 서로 다른 메모리 위치로 간주됨 | 메모리 위치는 이제 저장 공간을 가리킴 |