Embedded C++ for Real Systems · 0/41
Embedded C++ for Real Systems — 임베디드 모던 C++ 시리즈 소개
· Hawk · 6분 읽기
#이 시리즈를 쓰는 이유
“임베디드에서 C++를 쓰면 안 됩니다.”
이런 말을 들어본 적 있으신가요? 아직도 많은 임베디드 팀에서는 C++를 금기시합니다. 이유는 대략 이렇습니다:
- “C++는 무겁다”
- “예외 처리가 예측 불가능하다”
- “동적 할당이 위험하다”
- “런타임 오버헤드가 있다”
일부는 맞고, 일부는 틀립니다.
Modern C++의 많은 기능은 zero-cost abstraction입니다. 컴파일 타임에 모든 것이 결정되고, 런타임 오버헤드는 없습니다. 이 시리즈는 임베디드에서 C++를 안전하고 효율적으로 사용하는 방법을 다룹니다.
#대상 독자
-
C에서 C++로 전환하려는 임베디드 개발자
- “C++를 써도 될까?” 고민 중인 분
- 팀에 C++ 도입을 설득해야 하는 분
-
C++를 쓰고 있지만 확신이 없는 분
- “이렇게 해도 되나?” 싶은 코드가 있는 분
- Best practice를 알고 싶은 분
-
Modern C++ 기능을 임베디드에 적용하고 싶은 분
- C++11/14/17/20/23 기능 중 뭘 써도 되는지
- 어떤 기능은 피해야 하는지
#시리즈 구성
총 5개 Part, 40개 글로 구성됩니다.
C++ 기초부터 zero-cost abstraction, 메모리 관리, 고급 패턴, 하드웨어 추상화까지 체계적으로 다룹니다.
#Part 1: C++ in Embedded Context (8개)
임베디드에서 C++를 사용하는 기본 원칙을 다룹니다.
| # | 글 제목 | 핵심 내용 |
|---|---|---|
| 1-01 | C++ vs C: 무엇이 다른가 | 오버헤드 분석, 장단점 |
| 1-02 | 컴파일러 플래그 가이드 | -fno-exceptions, -fno-rtti, -Os |
| 1-03 | 런타임 요구사항 | libstdc++, newlib, 최소 런타임 |
| 1-04 | 코드 크기 분석 | bloat 원인, 측정 방법 |
| 1-05 | ABI 호환성 | C/C++ 혼합, name mangling |
| 1-06 | 스타트업 코드 | static 생성자, __libc_init_array |
| 1-07 | 링커 스크립트와 C++ | .init_array, 섹션 배치 |
| 1-08 | C++ 표준 선택 | C++11/14/17/20/23 비교 |
#Part 2: Zero-Cost Abstractions (10개)
런타임 비용 없이 추상화하는 방법을 다룹니다.
| # | 글 제목 | 핵심 내용 |
|---|---|---|
| 2-01 | RAII 기초 | 리소스 관리, 소멸자 보장 |
| 2-02 | RAII 실전 패턴 | Lock, Handle, ScopedXxx |
| 2-03 | constexpr 기초 | 컴파일 타임 계산 |
| 2-04 | constexpr 고급 | LUT 생성, CRC 테이블 |
| 2-05 | consteval과 constinit | C++20 기능 |
| 2-06 | Templates 기초 | 함수/클래스 템플릿 |
| 2-07 | Templates 비용 분석 | 코드 bloat 측정, 제어 |
| 2-08 | Static Polymorphism | CRTP, virtual 없이 다형성 |
| 2-09 | Type Traits 활용 | std::is_*, SFINAE |
| 2-10 | Concepts (C++20) | 템플릿 제약, 가독성 |
#Part 3: Memory & Error Handling (10개)
메모리와 에러를 안전하게 다루는 방법을 다룹니다.
| # | 글 제목 | 핵심 내용 |
|---|---|---|
| 3-01 | 동적 할당 없이 C++ 쓰기 | std::array, static 할당 |
| 3-02 | Custom Allocator 기초 | Allocator 인터페이스 |
| 3-03 | Pool Allocator 구현 | 고정 크기 블록 |
| 3-04 | std::pmr 활용 | polymorphic_allocator |
| 3-05 | No-Exception 설계 | -fno-exceptions 환경 |
| 3-06 | 에러 처리 패턴 | error code, optional |
| 3-07 | std::expected (C++23) | Result 타입 |
| 3-08 | No-RTTI 설계 | typeid 없이 타입 정보 |
| 3-09 | 스마트 포인터 선택 | unique_ptr vs shared_ptr |
| 3-10 | 소유권 모델 | Ownership, borrowing |
#Part 4: Advanced Patterns (8개)
고급 C++ 패턴을 임베디드에 적용합니다.
| # | 글 제목 | 핵심 내용 |
|---|---|---|
| 4-01 | Intrusive Containers | 동적 할당 없는 자료구조 |
| 4-02 | ETL 라이브러리 | Embedded Template Library |
| 4-03 | Lock-free 기초 | atomic, CAS |
| 4-04 | Lock-free Container | queue, stack |
| 4-05 | Type-safe Flags | enum class, 비트 플래그 |
| 4-06 | State Machine | 타입 안전한 상태 머신 |
| 4-07 | Compile-time FSM | constexpr 상태 머신 |
| 4-08 | Singleton 대안 | 의존성 주입, static |
#Part 5: Hardware Abstraction (4개)
C++로 하드웨어를 추상화하는 방법을 다룹니다.
| # | 글 제목 | 핵심 내용 |
|---|---|---|
| 5-01 | Register 추상화 | 타입 안전한 MMIO |
| 5-02 | GPIO 추상화 | 템플릿 기반 GPIO |
| 5-03 | Peripheral 추상화 | UART, SPI, I2C |
| 5-04 | HAL 설계 패턴 | 범용 HAL 구조 |
#학습 로드맵
- C++ 도입 검토 중 — Part 1 (기초) → Part 2-01~04 (RAII, constexpr)
- 이미 C++ 사용 중 — Part 2 (zero-cost) → Part 3 (메모리/에러) → Part 4 (패턴)
- 하드웨어 추상화 설계 — Part 2-06~08 (템플릿) → Part 5 (HAL)
#핵심 원칙
#1. 측정 가능한 주장만 한다
- “빠르다” → “어셈블리 N줄, 사이클 M개”
- “안전하다” → “컴파일 타임에 검증됨”
- Godbolt(Compiler Explorer)로 확인
#2. 대안을 제시한다
- “이건 쓰지 마세요” → “대신 이걸 쓰세요”
- 금지만 하지 않고 해결책 제공
#3. C를 비하하지 않는다
- C가 더 적합한 상황도 있음
- 부트 코드, 극소형 MCU, 인증 제약
#핵심 질문
시리즈 전체를 관통하는 질문:
- 이 기능이 런타임 비용을 추가하는가?
- 이 기능이 디버깅을 더 쉽게 만드는가?
- 이 기능이 코드 품질을 끌어올리는가?
- 바이너리 크기가 감당 가능한가?
#대상 환경
| 항목 | 기준 |
|---|---|
| 아키텍처 | ARM Cortex-M/A, RISC-V |
| OS | bare-metal, FreeRTOS, Zephyr |
| 컴파일러 | GCC, Clang, ARM Compiler |
| 플래그 | -fno-exceptions, -fno-rtti |
| 할당 | 정적 우선, 제한된 동적 |
| 중요 지표 | 코드 크기, latency, determinism |
#컴파일러 플래그 가이드
# 기본 설정CXXFLAGS += -std=c++17CXXFLAGS += -fno-exceptionsCXXFLAGS += -fno-rttiCXXFLAGS += -fno-threadsafe-statics
# 최적화CXXFLAGS += -Os # 또는 -O2CXXFLAGS += -flto # Link Time Optimization
# 경고CXXFLAGS += -Wall -Wextra -WpedanticCXXFLAGS += -Werror
# ARM 특화CXXFLAGS += -mcpu=cortex-m4CXXFLAGS += -mthumbCXXFLAGS += -mfloat-abi=hard#사전 지식
- C 프로그래밍 (포인터, 구조체)
- 기본적인 C++ 문법
- 임베디드 기초 (레지스터, 인터럽트)
- 컴파일/링크 과정 이해
#레퍼런스
서적
- Effective Modern C++ - Scott Meyers
- C++ Core Guidelines - Stroustrup & Sutter
- Real-Time C++ (4th ed) - Christopher Kormanyos
- Large-Scale C++ Volume I - John Lakos
온라인
컨퍼런스
- CppCon Embedded Track
- Meeting C++ Embedded
- Embedded World
#이 시리즈의 목표
이 시리즈를 완주하면:
- C++ 도입 여부를 판단할 수 있다
- zero-cost abstraction을 활용할 수 있다
- 메모리 안전한 코드를 작성할 수 있다
- 예외/RTTI 없이 설계할 수 있다
- 하드웨어를 타입 안전하게 추상화할 수 있다
- 코드 bloat를 통제할 수 있다
Embedded C++ for Real Systems · 1 of 41
- 1Embedded C++ for Real Systems — 임베디드 모던 C++ 시리즈 소개
- 2임베디드 C++ vs C — 런타임·코드 크기·ABI 관점 비교
- 3임베디드 C++ 컴파일러 플래그 분석 — -fno-rtti·-fno-exceptions·-Os
- 4임베디드 C++ 런타임 요구사항 — libstdc++·newlib·crt0 분석
- 5C++ 코드 크기 분석 — 가상 함수·템플릿·예외 비용 추적
- 6C++ ABI 호환성 — Itanium ABI·name mangling·vtable 레이아웃
- 7C++ 스타트업 코드 분석 — .init_array·전역 생성자 호출 순서
- 8임베디드 C++ 링커 스크립트 — vtable·정적 객체 배치 추적
- 9임베디드 C++ 표준 선택 가이드 — C++11/14/17/20/23 트레이드오프
- 10임베디드 RAII 기초 — 리소스 안전성과 결정적 소멸 보장
- 11임베디드 RAII 실전 패턴 — Lock·Pin·DMA·Power 관리
- 12constexpr 기초와 임베디드 적용 — 컴파일 타임 계산 활용
- 13constexpr 고급 활용 — 룩업 테이블·CRC·해시 컴파일 타임 생성
- 14consteval과 constinit 분석 — C++20 컴파일 타임 강제 메커니즘
- 15임베디드 Templates 기초 — 타입 안전과 코드 재사용 분석
- 16Template 비용 분석 — 코드 폭증·인스턴스화·디버그 정보 측정
- 17CRTP 패턴 분석 — vtable 없는 정적 다형성
- 18Type Traits 임베디드 활용 — SFINAE·is_pod·컴파일 타임 검사
- 19C++20 Concepts 활용 — 템플릿 제약과 가독성 개선
- 20동적 할당 없는 임베디드 C++ — placement new·정적 객체·풀
- 21Custom Allocator 기초 — std::allocator 인터페이스 분석
- 22Pool Allocator 구현 — Fixed-Size Block과 O(1) 보장
- 23std::pmr 임베디드 활용 — Polymorphic Memory Resource 분석
- 24No-Exception C++ 설계 — 코드 크기·결정성 트레이드오프
- 25임베디드 에러 처리 패턴 — Result·errno·optional 비교
- 26std::expected 분석 — C++23 결과 타입과 에러 전파
- 27No-RTTI C++ 설계 — dynamic_cast 제거와 정적 타입 분기
- 28임베디드 스마트 포인터 선택 — unique·shared·custom 비교
- 29임베디드 C++ 소유권 모델 — single·shared·borrow 패턴
- 30Intrusive Containers 분석 — 동적 할당 없는 컨테이너 설계
- 31ETL 라이브러리 분석 — Embedded Template Library의 STL 대체
- 32임베디드 Lock-free 기초 — atomic·memory ordering·CAS
- 33Lock-free Container 구현 — SPSC Queue·Ring Buffer
- 34Type-safe Flags 패턴 — Enum Class·Strong Typedef·Tag
- 35임베디드 State Machine 패턴 — Variant·Visitor·Table-driven 비교
- 36Compile-time FSM 구현 — 템플릿으로 상태 전이 검증
- 37Singleton 대안 패턴 — Service Locator·Static Init·Phantom
- 38MMIO Register 추상화 — 타입 안전한 비트 필드 접근
- 39GPIO 추상화 패턴 — Template·Concept으로 보드 독립성
- 40Peripheral 추상화 — UART·SPI·I2C 공통 인터페이스 설계
- 41임베디드 HAL 설계 패턴 — Static·Dynamic·Hybrid 비교
관련 글
이 글을 참조하는 글 (5)
- C 런타임 crt0 분석 — Stack·BSS Zero·Data Copy·atexit— Modern Embedded Recipes
- 임베디드 스타트업 코드 분석 — Reset_Handler·Vector Table·SystemInit— Modern Embedded Recipes
- ELF 파일 구조 분석 — Section·Segment·Symbol Table·DWARF— Modern Embedded Recipes
- ARM Cortex-M 시리즈 비교 — M0·M3·M4·M7·M33·M55 분석— Modern Embedded Recipes
- Modern Embedded Recipes — 모던 임베디드 실전 레시피 시리즈 소개— Modern Embedded Recipes