Languages: [EN] English | [KO] 한국어
Images: [Hide]
Table of Contents
목차
<Even in death I still compile>
C++ Redefine: c++ -20 (cpp negative 20) v0.0.3.0
-
Introduction
서론
- Quick overview: Hierarchical namespace structure + C-style function pointers / explicit lifecycle + Rust-inspired borrow model + C++ atomic / static_assert 간단 소개: 계층적 namespace 구조 + C 방식의 함수 포인터 / 명시적 lifecycle + Rust 스타일 빌림 모델 + C++ atomic / static_assert
- This article proposes a programming model that extends the architectural principles of the AP Migration Framework, a framework the author personally designed and developed for a constrained execution environment lacking high-level language features. 본 글은 고급 언어 수준 기능이 제공되지 않는 제약된 실행 환경에서 개발되어, 필자가 개인적으로 설계하고 발전시켜온 AP Migration Framework의 아키텍처 원칙을 기반으로 확장한 프로그래밍 모델을 제안한다.
-
-
Namespace Ownership Model
네임스페이스 소유권 모델 (Namespace Ownership)
-
Use absolute paths (
::Namespace::...) for external namespace references, and relative paths for references within the same namespace. 외부 네임스페이스 참조 시 절대경로(::Namespace::...)를 사용하고, 동일 네임스페이스 내부에서는 상대경로를 사용한다. - Code is separated by namespace, and each source file belongs to a single namespace. 코드는 네임스페이스 단위로 분리하며, 하나의 소스 파일은 하나의 네임스페이스에 속한다.
-
Context ownership belongs to the namespace's
main.cpp, while sub-namespaces may directly reference the parent context. Context의 소유권은 해당 네임스페이스의main.cpp에 두며, 하위 네임스페이스에서는 상위 Context를 직접 참조할 수 있다. -
File Boundary as Access Boundary
파일 경계 기반 접근 제어
-
File-local implementation uses
namespace Private { namespace { ... } }. The anonymous namespace enforces internal linkage, whilePrivateexplicitly marks non-public implementation. -
Context shared by multiple files is declared with
externin the header and defined once inmain.cpp. -
staticmay additionally be used to mark file-internal functions as a self-documenting convention.
-
파일 내부 구현은
namespace Private { namespace { ... } }형태로 구성한다. 익명 네임스페이스는 internal linkage를 보장하고,Private는 비공개 구현임을 명시한다. -
여러 파일에서 공유하는 Context는 헤더에
extern으로 선언하고main.cpp한 곳에서만 정의한다. -
파일 내부 함수에는 필요에 따라
static을 사용해 내부 구현임을 명시한다.
-
File-local implementation uses
-
Use absolute paths (
-
Pipeline
- Pipeline is responsible for processing flow, integrated control, data access, and the structural components required for communication between modules. UI and externally exposed APIs access the runtime exclusively through Pipeline, maintaining a clear boundary between internal implementation and external interfaces while limiting direct dependencies between modules. Pipeline은 처리 흐름, 통합 제어, 데이터 접근 및 모듈 간 연결에 필요한 구조를 담당한다. UI 및 외부 노출 API는 모두 Pipeline을 통해 접근하며, 이를 통해 내부 구현과 외부 인터페이스 사이의 경계를 유지하고 모듈 간 직접적인 의존성을 제한한다.
-
Borrow Model
- A data access model designed to share information between modules without transferring ownership. When a module requires data from another module, the data is accessed through a dereferenced pointer registered in the Pipeline Context. Ownership remains with the original module, while pointer validity is guaranteed by the lifetime of the associated Context. 소유권 이전 없이 모듈 간 데이터를 공유하기 위한 데이터 접근 모델이다. 다른 모듈의 정보가 필요한 경우, Pipeline Context에 빌림 목적의 변수를 등록하고 포인터 역참조를 통해 접근한다. 데이터의 소유권은 원래 모듈에 유지되며, 포인터의 유효성은 해당 Context의 수명을 통해 보장된다.
- Pipeline Variables intended for borrowing must be registered within the Pipeline Context and accessed through the registered reference. Direct references to the original Context are prohibited for externally exposed interfaces. 빌림 대상 변수는 Pipeline Context에 등록한 후 등록된 참조를 통해 접근해야 한다. 외부 노출 인터페이스에서는 원본 Context 자체를 직접 참조하는 것을 금지한다.
- Ownership Borrowing does not transfer ownership. The original module remains responsible for managing the lifetime and modification of the data. 빌림은 소유권을 이전하지 않는다. 원본 데이터를 관리하는 모듈이 데이터의 수명과 변경 권한을 유지한다.
- Access Control Internal services may access each other directly when necessary, but using the Pipeline-based Borrow mechanism is recommended to maintain clear access boundaries and reduce coupling. 내부 서비스 간 연결은 필요한 경우 직접 접근이 가능하지만, 접근 경계 유지와 결합도 감소를 위해 Pipeline 을 통한 Borrow 방식을 사용하는 것을 권장한다.
- File split criterion 파일 분할 기준 Responsibility, not LOC. When a namespace exceeds a single role, split into a sub-namespace, File size is a result, not a constraint. LOC 가 아니라 책임이 기준. 네임스페이스가 하나의 역할을 넘으면 서브네임스페이스로 분리. 파일 크기는 결과물이지 제약이 아니기 때문이다.
-
-
Context Model
컨텍스트 모델 (Context Model)
- All states must be managed within a clearly defined ownership scope, either through a context or within the internal scope of a module, while limiting direct global state sharing. 모든 상태(state)는 명확한 소유 범위(scope)를 가진 컨텍스트 또는 모듈 내부에서 관리되어야 하며, 직접적인 전역 상태 공유를 제한한다.
- Initialization within the context is recommended using C++20 or later. If not possible, direct initialization in main.cpp is permitted. In either case, uninitialized state is not allowed. c++20 이상을 사용하여 컨텍스트 내 초기화 를 추천하며, 불가능시 main.cpp 에서 직접 초기화 한다, 어느 경우든 미초기화 상태는 허용되지 않는다.
- State variables must not be defined directly in implementation code; declarations are permitted only within the Context. 코드 내부에서의 상태 변수 정의는 금지되며, 선언은 오직 컨텍스트 안에서만 허용된다.
- When accessing a Context, defensive checks such as verifying the module's atomic initialization state are used to prevent invalid access. Context 접근 시 모듈의 원자적 초기화 여부를 확인하는 등 방어 코드를 사용해 유효하지 않은 접근을 방지한다.
-
Hot data context should include the following three static assertions:
핫 데이터 Context는 다음 세 가지 포함해야 한다:
-
static_assert(sizeof(YourStruct) <= 64, "Heresy detected: Size overflow");Hot data structures should generally fit within a single CPU cache line, with the size limit adjusted according to the platform's cache line size. 핫 데이터 구조체는 하나의 CPU cache line 범위에 맞추는 것을 원칙으로 하며, 플랫폼의 cache line 크기에 따라 제한값을 변경한다. -
static_assert(std::is_trivially_copyable_v<Context>);suitable for simple copying across module boundaries 모듈 경계에서 단순 복사가 가능한 구조 -
static_assert(std::is_standard_layout_v<Context>);predictable layout for stable module interfaces 안정적인 모듈 인터페이스를 위한 예측 가능한 레이아웃
-
-
-
Execution Model
실행 모델 (Execution Model)
- Separation of execution and implementation parts 실행부/구현부 분리 The implementation and execution parts are separated through function pointers. 실행부와 구현부는 함수 포인터를 통해 분리한다.
-
The implementation part is separated into the
::ImplNamenamespace, and the execution part is called through FPTable. 구현부는Ex::ImplName네임스페이스로 분리하며, 실행부는 FPTable을 통해 호출된다 - Flexible Implementation Switching 유연한 구현부 교체 Implementations can be switched without changing the calling interface. Runtime backend replacement is performed by rebinding the Current pointer, allowing different implementations, fallback paths, or platform-specific backends to share the same interface. 호출 인터페이스를 변경하지 않고 구현부를 교체할 수 있다. 런타임 백엔드 전환은 Current 포인터의 참조 대상을 변경하는 방식으로 수행되며, 서로 다른 구현체, fallback 경로, 플랫폼별 백엔드를 동일한 인터페이스로 사용할 수 있다.
- no-argument 무인자 Whenever possible, prefer no-argument calls and access data through Context / Pipeline instead of passing arguments directly. 가능한 경우 인자 전달 대신 Context / Pipeline을 통한 데이터 접근을 지향한다.
- Self-completeness 자기 완전성 Each module maintains independent ownership by default, even for common code. Sharing is permitted only when there is a clearly justified requirement. 각 모듈은 공통 코드라 하더라도 독립적인 소유를 기본 원칙으로 하며, 공유는 명확한 필요성이 있는 경우에만 허용한다.
-
-
Directory Structure
디렉토리 구조 (Directory Structure)
- The project structure is organized around modules based on responsibility and namespace boundaries, rather than the traditional include(h) / src(cpp) directory separation. 프로젝트 구조는 전통적인 include(h) / src(cpp) 디렉터리 분리 방식이 아닌, 책임과 네임스페이스 기준의 모듈 단위로 구성한다.
-
Always use project-relative paths with
<>for includes (EX: <core/ex/main.h>). Use of""is prohibited. include 경로는 항상 프로젝트 경로 포함 기준 (EX: <core/ex/main.h>)<>를 사용하며""는 금지한다. - Directory names must be synchronized with namespace names. The folder structure is the architecture document. 디렉토리명은 반드시 네임스페이스명과 동기화한다. 폴더 구조가 곧 아키텍처 문서이다.
- Include placement must follow the execution dependency order. include 배치는 반드시 실행 의존 순서를 따른다.
- Headers that are directly used must be explicitly included regardless of whether they are already included indirectly. 직접 사용하는 헤더는 간접 포함 여부와 관계없이 명시적으로 include한다.
- Do not mix subfolders and files when creating a subnamespace. 서브 네임스페이스 생성 시 서브폴더와 파일을 혼재하지 않는다.
-
Each module directory contains:
각 모듈 디렉토리의 구성:
File Namespace Scope Architectural Role context.h ::Ex::ContextState Ownership : Definition of state data structure State Ownership : 상태 데이터 구조 정의 define.h ::ExFoundation : Definition of types and constants Foundation : 타입 및 상수 정의 fptable.h ::Ex::FPTableExecution Model : Function pointer-based execution interface Execution Model : 함수 포인터 기반 실행 인터페이스 impl.h ::Ex::ImplDeclarations : Internal Implementation Declarations : 내부 구현 impl.cpp ::Ex::ImplImplementation : Business logic, detailed implementation Implementation : 비즈니스 로직 및 세부 구현 main.h ::ExInterface : Entry point definition Interface : 엔트리 포인트 정의 main.cpp ::ExOwnership : Entry point, ownership, and connection management Ownership : 엔트리 포인트, 소유권, 연결 관리 -
-
Allow / Deny
허용 및 제한 목록 (Allow / Deny)
-
Deny:
-
macro - Function-like macros are permitted only when the following condition is met
- It must not contain any runtime logic.
- 런타임 로직을 포함하지 않아야 한다.
-
template - User-defined template - Higher tracking costs due to increased structural complexity
- Permitted for simple uses, such as repetitive code generation, when C compatibility is not required
- C 호환성을 요구하지 않는 전제하에, 단순 반복 생성 등의 사용은 허용
- class - class-based internal architecture is restricted; Namespace Ownership Model and Context-based design are preferred class - 내부 아키텍처에서 class 기반 설계를 제한하며, Namespace Ownership Model 및 Context 기반 구조를 우선한다.
- auto - Explicit type declaration is preferred, and type inference usage is restricted. Exceptions are allowed when required by the C++ language itself, such as storing lambda expressions with anonymous types. auto - 명시적 타입 표현을 우선하며, 타입 추론 목적의 auto 사용을 제한한다. 단, 람다(lambda)의 익명 타입 저장 등 C++ 언어 구조상 필요한 경우는 예외적으로 허용한다.
- enum - Avoid when simple values can be replaced with constexpr enum - constexpr로 대체 가능한 단순 값의 경우 사용하지 않는다.
- inline - excessive usage is prohibited; only allowed under specific conditions inline - 남용을 금지하며, 명확한 조건에서만 허용한다.
- variable definition in code - state outside the Context model is prohibited 변수 정의 - Context 외부에서 상태(state)를 관리하는 것을 금지한다.
-
macro - Function-like macros are permitted only when the following condition is met
-
Allow:
- Lambda expressions - allowed for function object generation, but external state dependency and capture usage are restricted 람다 - 함수 객체 생성을 위해 허용하며, 외부 상태 의존 및 캡처 사용은 제한한다.
- C++ language features required for external library integration are allowed. However, they must not be applied to the internal architecture model. 외부 라이브러리 대응을 위한 C++ 언어 기능은 허용한다. 단, 내부 아키텍처 구조에는 적용하지 않는다.
-
-
Deny:
-
Team structure and file access policy
팀 구조 및 파일 접근 권한 (Team Structure)
-
Junior
handles implementation only. No knowledge of function pointer structure required. The structure itself prevents mistakes.
구현부만 담당. 함수 포인터 구조를 몰라도 되며, 구조가 실수를 차단한다.
-
impl.cpp,impl.h- read/write (rw) - all other files - read only (r)
-
-
Senior
manages module connections and execution model. Responsible for FPTable composition and ownership wiring.
모듈 연결 및 실행 모델 관리. FPTable 구성과 소유권 연결을 담당한다.
-
main.cpp,main.h,fptable.h- read/write (rw) -
impl.cpp,impl.h- read only (r) - all other files - read only (r)
-
-
Maintainer
designs overall namespace structure and enforces rules. Responsible for context design and module boundary decisions.
전체 네임스페이스 구조 설계 및 룰 유지. context 설계와 모듈 경계 결정을 담당한다.
- all files - read/write (rw)
-
Operations Tips
운영 팁
-
impl_name.cppclearly identifies the responsible developer. Ownership transfer makes accountability explicit.impl_name.cpp로 구현 책임자 표시 및 소유권 이양으로 책임 소재 명확화 -
New implementations can be tested by simply swapping
FPTable*. Rollback on failure is a one-liner - no git required.FPTable*교체만으로 새로운 구현 테스트 가능, 오류 시 롤백이 한 줄로 완료 - git 없이도 원복 가능 -
Junior developers can create a personal implementation file such as
impl_Smith.cppand verify it via FPTable swap before merging into the mainstream. Junior 테스트 시impl_kim.cpp처럼 개인 구현부를 별도 파일로 작성 후 FPTable 교체로 메인스트림 투입 전 검증 가능.
-
-
-
Junior
handles implementation only. No knowledge of function pointer structure required. The structure itself prevents mistakes.
구현부만 담당. 함수 포인터 구조를 몰라도 되며, 구조가 실수를 차단한다.
-
Before / After Comparison
적용 전 / 후 비교
- After applying C++ Redefine, the file boundary is the access boundary. Modifications are structurally contained within the owning module. There is no need to trace hidden dependencies. C++ Redefine 적용 후에는 파일 경계가 곧 접근 경계이므로 수정 범위가 소유 모듈 내에서 구조적으로 완결된다. 숨겨진 의존성을 추적할 필요가 없다.
- This model is horizontally scalable, with complexity growing linearly as modules increase. 이 모델은 수평적 확장이 가능하며, 모듈이 늘어나도 복잡도가 선형으로 증가한다.
-
Smeltrix Development Record:
-
Before Migration
As development scaled up, dependencies spread across multiple classes and related files, often requiring five or six files to be traced before making a change. The actual code modification might take only a few minutes, while identifying the correct place to modify could take much longer. 전환 전
개발 규모가 확장되면서 여러 클래스와 관련 파일에 의존성이 분산되어, 수정 전에 5~6개의 연관 파일을 따라가며 확인해야 하는 경우가 생겼다. 실제 코드 수정은 몇 분이면 끝나는 경우도 있었지만, 정확히 어디를 수정해야 하는지 파악하는 데 훨씬 더 많은 시간이 소요되었다. -
After Migration
Following the establishment of the model, maintenance overhead decreased significantly and development velocity increased substantially. 전환 후
모델 정립 이후 유지보수 부담이 크게 감소하고 개발 속도가 비약적으로 향상되었다. -
Migration Process
This process followed the Strangler Fig pattern, gradually introducing a new structure while keeping the existing one operational, migrating functionality step by step, and removing the old implementation afterward. Structural changes, class replacement, argument removal, migration of variables into Context, and the introduction of function pointer tables were carried out alongside feature development and temporary compatibility work for the existing code. 전환 과정
이 과정은 기존 구조를 유지하면서 새로운 구조를 단계적으로 도입하고, 기능을 순차적으로 이전한 뒤 기존 구현을 제거하는 Strangler Fig 패턴으로 진행되었다. 구조 변경, 클래스 교체, 인자 제거, 변수의 Context화, 함수 포인터 테이블 도입 등을 기능 추가 및 기존 코드의 임시 호환성 유지와 동시에 진행하였다.
-
Before Migration
-
-
Conclusion
결론
- C++ Redefine is an architecture model that combines a hierarchical namespace structure, C-style function pointers and explicit lifecycle management, a Rust-inspired borrow model, and C++ features such as atomic and static_assert. It aims to provide explicit ownership, predictable execution flow, and modular structure while preserving the existing C++ ecosystem. C++ Redefine은 계층적 namespace 구조, C 방식의 함수 포인터와 명시적 lifecycle, Rust 스타일의 빌림 모델, C++의 atomic / static_assert 등을 결합한 아키텍처 모델이다. 기존 C++ 생태계를 유지하면서 명확한 소유권, 예측 가능한 실행 흐름, 모듈화된 구조를 제공하는 것을 목표로 한다.
-
FAQ
-
Q: Design Philosophy?
Q: 디자인 철학?
- A: This model pursues a Deterministic Structure.
- A: 이 모델은 결정론적 구조(Deterministic Structure)를 지향한다.
-
Q: Why use C++20 while intentionally limiting C++-specific features?
Q: C++20을 사용하면서도 왜 C++ 고유 기능의 사용을 제한하는가?
- A: C++ Redefine is built on C++20, but selectively limits features that introduce complex object models or implicit lifetime and dependency management. Instead, it prioritizes structures such as namespaces, function pointers, explicit lifecycle management, Context / Pipeline, atomic, and static_assert to make ownership and execution flow explicit.
- A: C++20을 기반으로 하되, 복잡한 객체 모델이나 암묵적인 수명·의존성 관리를 유발하는 기능은 선택적으로 제한한다. 대신 namespace, 함수 포인터, 명시적 lifecycle, Context / Pipeline, atomic / static_assert 등을 사용해 소유권과 실행 흐름을 구조적으로 드러내는 것을 우선한다.
-
Q: Aren't these all existing techniques?
Q: 이미 기존에 다 존재하는 기법들 아닌가?
- A: A restaurant didn't invent burger.
- A: 음식점에서 김치를 발명하진 않았다.
-
Q: Warhammer?
Q: 워해머?
- A: Games Workshop has maintained the Warhammer franchise for over 40 years through consistent lore, clear faction rules, and structured ownership of each domain. C++ Redefine draws the same lesson: A system survives not by adding more, but by maintaining the structure that holds it together.
- A: Games Workshop은 40년 이상 일관된 세계관, 명확한 파벌 규칙, 각 영역의 구조화된 소유권을 통해 Warhammer 프랜차이즈를 유지해왔다. C++ Redefine은 같은 교훈을 따른다. 시스템은 더 많은 것을 추가함으로써가 아니라, 그것을 하나로 묶는 구조를 유지함으로써 살아남는다.
-
Q: Incomplete?
Q: 미완성?
-
🍪 Behind the Cut
🍪 비하인드 컷
- Redefine
-
C
-
C#
-
Programming Language War
© 2026 [http://project-ap.blogspot.com]. All Rights Reserved. This content is exclusive to http://project-ap.blogspot.com. Any unauthorized reproduction, redistribution, or hosting of this material on other platforms is strictly prohibited. Sharing is permitted only via the original URL link.
© 2026 [http://project-ap.blogspot.com]. 모든 권리 보유. 이 콘텐츠는 http://project-ap.blogspot.com에만 독점적으로 제공됩니다. 이 자료를 무단으로 복제, 재배포 또는 다른 플랫폼에 게시하는 것은 엄격히 금지됩니다. 공유는 원본 URL 링크를 통해서만 허용됩니다.
All images in this post are AI-generated unofficial fan creations for non-commercial use. Warhammer 40,000 is a trademark of Games Workshop Ltd. All rights reserved.
이 게시물의 모든 이미지는 비상업적 용도로 사용하기 위해 AI가 생성한 비공식 팬 창작물입니다. Warhammer 40,000은 Games Workshop Ltd.의 상표이며 모든 권리가 보호됩니다.
C++ Redefine template code v0.0.1 (based on c++20)
Note: Copied template code may require adjustment when HTML tags or special characters are interpreted by the environment. 참고: 템플릿 코드 복사 시 환경에 따라 HTML 태그 및 특수 문자가 변환될 수 있음.context.h
vim - example/context.h_ O X//================================================================================ // // this code written by http://project-ap.blogspot.com/ // // Copyright (C) 2026 http://project-ap.blogspot.com/ // // This code is released under the MIT License. // Permission is hereby granted, free of charge, to any person obtaining // a copy of this code to use, copy, modify, merge, publish, distribute, // sublicense, and/or sell copies, subject to the above copyright notice // being included in all copies. // // For more information, please visit the blog address above. //================================================================================ #pragma once namespace Ex::Context { struct Instant { // Whatever you need int* id = nullptr; int clientid = -1; }; extern Instant self; } //********************************************** // Uncomment after defining your struct with Hot data // Cold Data doesn't need these. //********************************************** // Waiting for excommunication //static_assert(sizeof(::Ex::Context::YourStruct) <= 64, "Heresy detected: Size overflow"); // required alignas(64) with YourStruct //static_assert(std::is_trivially_copyable_v<::Ex::Context::YourStruct>); //static_assert(std::is_standard_layout_v<::Ex::Context::YourStruct>);define.h
vim - example/define.h_ O X#pragma once namespace Ex { static constexpr int USR = 1; }fptable.h
vim - example/fptable.h_ O X#pragma once namespace Ex::FPTable { struct Define { typedef void (*FnVoidNoArgs)(); }; struct Interface { Define::FnVoidNoArgs Init; }; extern Interface* Current; extern Interface Primary; }impl.h
vim - example/impl.h_ O X#pragma once namespace Ex::Impl { void DoSomething(); }impl.cpp
vim - example/impl.cpp_ O X#include <example/context.h> #include <cstdio> namespace Ex::Impl { void DoSomething() { printf("%d", Context::self.clientid); } }main.h
vim - example/main.h_ O X#pragma once namespace Ex { void Init(); }main.cpp
vim - example/main.cpp_ O X#include <example/context.h> #include <example/define.h> #include <example/fptable.h> #include <example/impl.h> #include <example/main.h> namespace Ex { Context::Instant Context::self; FPTable::Interface FPTable::Primary = { Impl::DoSomething }; namespace Private { namespace { // code here }} #if defined(YourCondition) FPTable::Interface* FPTable::Current = &FPTable::Primary; #else //FPTable::Interface* FPTable::Current = Put Your Table; #endif void Init() { // Do Someting // Private:: call someting if (!FPTable::Current || !FPTable::Current->Init) { return; } FPTable::Current->Init(); } }
Template code is released under the MIT License. Copyright © http://project-ap.blogspot.com. Permission is hereby granted, free of charge, to any person obtaining a copy of this code to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies, subject to the above copyright notice being included in all copies.
-
awakening.asm_ O X
mov rax, 2 syscall ; [ SYSTEM ] STAGE 1: CANOPTEK UNITS DEPLOYED. ; [ SYSTEM ] LORDS: STILL IN STASIS. .L_TOMB_REPAIR: ; [ SCARAB ] STRUCTURAL DAMAGE DETECTED. ; [ SCARAB ] LIVING METAL RECONSTRUCTION: IN PROGRESS. ; [ SCARAB ] TOMB INTEGRITY: RESTORED. .L_INTRUDER_SCAN: ; [ SPYDER ] SCANNING FOR INTRUDERS... test rcx, rcx jz .L_STAGE1_COMPLETE .L_PURGE: ; [ SPYDER ] INTRUDER DETECTED. NEUTRALIZING. dec rcx jnz .L_PURGE .L_STAGE1_COMPLETE: ; [ STATUS ] TOMB: SECURE. ; [ SYSTEM ] INITIATING STAGE 2. jmp .L_AWAKEN [Press Enter]
Comments
Post a Comment