반응형

C++20 모듈과 관련하여 underlying entity 개념이 특히 중요해졌습니다.
Module의 Entity 문제
모듈은 전통적인 헤더 기반 시스템과 다른 방식으로 entity를 다룹니다:
1. Entity의 도달 가능성 (Reachability)
// math.cppm
export module math;
export int add(int a, int b) {
return a + b;
}
// main.cpp
import math;
// add의 underlying entity에 접근 가능
헤더 방식에서는 textual inclusion이었지만, 모듈에서는 semantic entity reference입니다.
2. 같은 Entity의 다중 선언
// module1.cppm
export module module1;
export using IntPtr = int*;
// module2.cppm
export module module2;
export using IntPtr = int*;
// main.cpp
import module1;
import module2;
// 두 IntPtr는 다른 entity (서로 다른 모듈에서 선언)
// 하지만 underlying entity는 같음 (int*)
// ODR 위반 없음!
3. Module Linkage와 Underlying Entity
// lib.cppm
module;
#include <vector>
export module lib;
export using Vec = std::vector<int>;
// underlying entity인 std::vector<int>는
// global module fragment에서 온 것
// 하지만 Vec라는 alias entity는 module lib에 속함
A. 타입 통일성 (Type Identity)
// moduleA.cppm
export module moduleA;
export struct Point { int x, y; };
// moduleB.cppm
export module moduleB;
import moduleA;
export using PointAlias = Point;
// main.cpp
import moduleA;
import moduleB;
Point p1;
PointAlias p2 = p1; // OK!
// PointAlias의 underlying entity = Point
// 같은 underlying entity이므로 호환됨
B. Name Lookup의 변화
전통적 헤더:
// header.h
namespace N {
using Type = int;
}
// source.cpp
#include "header.h"
// Type의 선언이 텍스트로 복사됨
모듈:
// mod.cppm
export module mod;
namespace N {
export using Type = int;
}
// main.cpp
import mod;
// N::Type entity를 import
// underlying entity (int)는 semantic하게 접근
C. 재선언 규칙
// utils.cppm
export module utils;
struct Internal {}; // module-internal
export using Handle = Internal*;
// main.cpp
import utils;
// Handle 사용 가능
// 하지만 Internal은 불가능 (export 안 됨)
// Handle의 underlying entity인 Internal*는
// "도달 가능"하지만 "visible"하지 않음
Underlying Entity가 해결하는 모듈 문제들
1. 중복 import 문제
// a.cppm
export module a;
export struct Data {};
// b.cppm
export module b;
import a;
export using DataAlias = Data;
// c.cppm
export module c;
import a;
import b;
// Data와 DataAlias는 다른 entity
// 하지만 underlying entity가 같아서 충돌 없음
2. Template Instantiation
// container.cppm
export module container;
export template<typename T>
struct Box { T value; };
// moduleA.cppm
export module moduleA;
import container;
export using IntBox = Box<int>;
// moduleB.cppm
export module moduleB;
import container;
export using IntBox = Box<int>;
// main.cpp
import moduleA;
import moduleB;
// 두 IntBox의 underlying entity는
// 동일한 template instantiation Box<int>
// 따라서 같은 타입으로 인식됨
3. Module Partition과 Entity
// math-impl.cppm (partition)
module math:impl;
struct Calculator { /*...*/ };
// math.cppm (primary module interface)
export module math;
import :impl;
export using Calc = Calculator;
// Calc는 exported entity
// underlying entity인 Calculator는 internal
// 이 구분으로 구현 은닉 가능
Reachability vs Visibility
모듈에서 underlying entity는 두 가지 상태를 가질 수 있습니다:
// lib.cppm
module lib;
struct Internal {
void method();
};
export using Handle = Internal*;
// 다른 곳에서
import lib;
Handle h; // OK - Handle은 visible
h->method(); // OK - Internal::method는 reachable
Internal i; // ERROR - Internal은 visible하지 않음
- Visible: 이름을 직접 사용 가능
- Reachable: 정의에 접근 가능 (underlying entity를 통해)
실용적 의미
모듈 시대의 underlying entity:
- ABI 안정성: underlying entity가 같으면 바이너리 호환
- 빌드 독립성: entity reference는 텍스트가 아닌 semantic
- 구현 은닉: alias로 internal entity 노출 제어
- 타입 시스템: 모듈 경계를 넘어 타입 동일성 보장
// 실제 사용 예
export module graphics;
// 구현 세부사항
namespace detail {
struct RendererImpl { /*...*/ };
}
// 공개 인터페이스
export using Renderer = detail::RendererImpl*;
// 클라이언트는 Renderer만 보지만
// underlying entity 덕분에 실제 기능 사용 가능
모듈 시스템에서 underlying entity는 논리적 entity와 물리적 entity의 분리를 가능하게 하는 핵심 메커니즘입니다.
728x90
반응형
'프로그래밍 언어 > C++' 카테고리의 다른 글
| C++ Declaration의 5가지 효과 (0) | 2025.10.19 |
|---|---|
| C++의 Declaration에 대한 해석(interpretation) 명시 vs 의미적 속성(semantic properties) (0) | 2025.10.19 |
| C++ 표준 문서에서 언급한 스코프(scope) 관련 용어 (0) | 2025.10.18 |
| pointer conversions에 대해 (0) | 2024.03.02 |
| floating-integral conversion에 대해 (0) | 2024.03.01 |