C++ (C++23)

Analysis against C++23 (ISO/IEC 14882:2024). Older C++ standards have substantially worse coupling properties; C++23 represents the best of what modern C++ offers.

This assessment applies the coupling account — coupling as access to a shared resource, and the coupling floor [1], [2] — and the knowledge-embodiment theorem [3]; the language is assessed against its official reference [4].

1 Assessment

This page assesses C++ in five parts: core coupling — what the language’s own constructs force; ecosystem coupling — what the surrounding platform, tooling, and community cost; engineering readiness — whether the artifact can be reproduced, verified, observed, worked in quickly, connected to other languages, and governed openly; the profile — the unscored facts a score cannot express; and the scoring detail — the mechanism marks and the arithmetic behind every score. A ✅ bullet marks a construct that helps. A ⚠️ or ❌ bullet marks a cost; the scoring model does not price every cost named here.

Core coupling 50/100 · Ecosystem coupling 61/100 · Engineering readiness 65/100

Note: The score reflects C++23 with modern idioms (smart pointers ≥ raw pointers, std::expected ≥ exceptions, modules ≥ headers, concepts ≥ unconstrained templates). Teams stuck on older standards or pre-modern coding styles will experience significantly worse coupling properties.

1.1 Core coupling

1.1.1 Type

  • ✅ Templates enable generic programming: Decouple algorithms from types
  • ✅ RAII separates resource management: Constructor acquires, destructor releases
  • ✅ Concepts (C++20) constrain templates: Clean error messages, explicit constraints decouple interface from implementation
  • ✅ Modules (C++20/23) decouple compilation: import replaces #include and removes header coupling, though headers remain for code not yet migrated
  • ✅ Deducing this (C++23): Eliminates const/non-const overload duplication
  • ⚠️ Multiple inheritance still available: Diamond problem possible (though final specifier helps)
  • ⚠️ Template metaprogramming still complex: Despite concepts, advanced templates couple to expertise
  • ❌ Macros couple: Preprocessor doesn’t respect scope (though modules reduce header macro issues)

1.1.2 Construction

  • ✅ Constructors separate: Copy, move, default constructors are distinct
  • ✅ Move semantics decouple: Transfer ownership without copying
  • ✅ Designated initializers (C++20): Named initialization decouples from parameter order
  • ❌ Constructors can throw: Exception during construction couples cleanup
  • ⚠️ Two-phase initialization still possible: Though discouraged by modern idioms
  • ❌ Global state common: Static variables, singletons (not enforced away)

1.1.3 Memory

  • ✅ RAII decouples resource management: Destructors run deterministically, no GC needed
  • ✅ Smart pointers eliminate manual delete: unique_ptr, shared_ptr are idiomatic (manual new/delete is a code smell in modern C++)
  • ✅ std::span/std::mdspan (C++20/23): Non-owning one- and multi-dimensional views decouple algorithms from container types and memory layout
  • ✅ Explicit lifetime management (C++23): std::start_lifetime_as for safe low-level patterns
  • ⚠️ shared_ptr has atomic ref counting cost: And circular references need weak_ptr
  • ⚠️ Raw pointer escape hatches exist: A raw pointer and a reference can alias the same object with no owner stated, though idiomatic C++23 uses spans and smart pointers (M4)
  • ✅ No GC, deterministic: Full control over allocation timing
  • ❌ Undefined behavior still exists: Buffer overruns, null derefs possible when using raw pointers/functions

1.1.4 Error

  • ✅ std::expected and std::optional monadic operations (C++23): and_then, transform, or_else make error and absence handling composable and type-safe
  • ❌ Exceptions still exist and remain unchecked: std::expected is idiomatic and preferred, but exceptions are still in the language and used in the standard library
  • ✅ std::stacktrace (C++23): Provides unwinding visibility, addressing historical debugging pain
  • ✅ std::variant: Type-safe discriminated union for error discrimination

1.1.5 Concurrency

  • ⚠️ Shared mutable state default: Mutexes required, though lock-free patterns are achievable
  • ✅ std::jthread (C++20): Auto-joining threads with cancellation via std::stop_token
  • ✅ std::latch, std::barrier, std::semaphore (C++20): Higher-level synchronization primitives
  • ✅ std::generator (C++23): Coroutine-based generator decouples producer from consumer
  • ❌ Data races are undefined behavior: No compile-time prevention (unlike Rust)
  • ⚠️ Memory model still complex: Atomic operations require deep understanding

1.1.6 Platform

  • ✅ No vendor owner: The language is standardised by ISO/IEC and implemented independently by GCC, Clang, and MSVC, so no single vendor controls the standard
  • ✅ No required platform runtime: A program compiles to native code and needs no C++-specific virtual machine or vendor service
  • ✅ Every mainstream target is supported: Compilers and standard libraries exist for Linux, macOS, Windows, and embedded and bare-metal targets
  • ✅ One source base for several implementations: Code that stays in the portable subset compiles under GCC, Clang, and MSVC, so the project is not bound to one compiler

1.1.7 Trade-offs (not coupling)

  • RAII vs. Exceptions: Exception during construction couples cleanup to unwinding, may leak
  • Zero-Cost Abstractions vs. Compile Time: Templates (and now concepts + modules) couple build speed to abstraction usage
  • C Compatibility vs. Modern Features: Legacy C patterns can couple to modern C++ code when used
  • Standard Versions: C++11/14/17/20/23 couple codebases to version choices; modern C++ is largely additive since C++11
  • Safety vs. Performance: std::span bounds-checking is opt-in; raw pointer escape hatches remain for performance

1.2 Ecosystem coupling

1.2.1 Performance

  • ✅ Zero-overhead abstraction: Pay only for what you use
  • ✅ No GC: Deterministic, predictable
  • ✅ Manual control: Full optimization control
  • ✅ Compile-time computation: Constexpr (expanded in C++23 — now covers std::bitset, std::unique_ptr, std::optional, std::variant, std::string, cmath functions)
  • ⚠️ Binary bloat: Templates can explode size (mitigated by explicit instantiations, LTO)

1.2.2 Ecosystem

  • ⚠️ No standard package manager: CMake + Conan/vcpkg are de facto standards, but fragmentation persists
  • ⚠️ Compilation speed: Templates + concepts + modules improve but still slower than Go/Rust
  • ✅ Excellent IDE support: CLion, Visual Studio, VSCode with clangd — all support C++23
  • ✅ Vast library ecosystem: Decades of libraries, Boost, Qt, etc.
  • ⚠️ Build system convergence improving: CMake dominates; vcpkg/Conan converging

1.2.3 Evolution

  • ✅ Additive since C++11: Code from C++11+ largely compiles under C++23 (removed features are rare and deprecated first)
  • ⚠️ Legacy C++98 burden: Old codebases still exist, but not a language-level problem for new code
  • ✅ 3-year standard cadence: Predictable evolution (C++23 → C++26 → C++29)
  • ⚠️ Feature complexity grows: Each standard adds more to learn

1.2.4 Domain

  • ✅ Excellent for systems: Performance critical code
  • ✅ Great for games: Industry standard
  • ✅ Strong for embedded: (with care, constexpr + templates help)
  • ✅ Good for high-performance: Finance, scientific computing
  • ⚠️ Not for web: Rare use case

1.2.5 Learning

  • ❌ Very steep: Massive language surface area accumulated over 40+ years
  • ❌ C++23 idioms are learnable but the full language is not: Smart pointers, expected, ranges, modules add to surface
  • ❌ Undefined behavior: Still exists and requires understanding to avoid
  • ✅ Excellent resources: Effective Modern C++, C++ Core Guidelines, cppreference

1.2.6 Syntax

  • ✅ Modules reduce header boilerplate: import std; replaces many #includes
  • ⚠️ Template syntax: <> remains noisy, though concepts improve readability
  • ✅ Designated initializers: Named member initialization improves readability
  • ✅ auto, structured bindings (C++17): Reduce verbosity

1.2.7 Testing

  • ✅ GTest, Catch2, doctest: Mature frameworks
  • ✅ Static analyzers: Clang-Tidy, CppCheck, and MSVC Code Analysis find some undefined behaviour before runtime, though no analyzer is sound or complete
  • ✅ Profilers: Excellent tooling (perf, VTune, Instruments)
  • ✅ std::stacktrace (C++23): Runtime stacktrace capture improves debugging
  • ⚠️ Template errors: Concepts (C++20) dramatically improve error messages, but edge cases remain

1.2.8 Security

  • ⚠️ Memory safety depends on idiom: std::span, std::mdspan, smart pointers are memory-safe; raw pointers and pointer arithmetic are not
  • ✅ Smart pointers + RAII eliminate most memory bugs in modern C++: unique_ptr prevents use-after-free, double-free
  • ✅ AddressSanitizer, MemorySanitizer: Compiler instrumentation catches memory bugs at test time
  • ❌ Unsafe escape hatches remain: reinterpret_cast, pointer arithmetic, manual new/delete still compile (Q1)

1.3 Engineering readiness

1.3.1 Reproducibility

  • ❌ Builds are not byte-reproducible by default.
  • ❌ Dependencies resolve without a lock by default.

1.3.2 Supply chain

  • ⚠️ Published packages carry no signed provenance by default.

1.3.3 Observability

  • ⚠️ The standard library has no structured logging.

1.3.4 Feedback

  • ❌ A change pays a slow build.

1.3.5 Interop

  • ✅ No charged mechanism in this dimension.

1.3.6 Governance

  • ✅ No charged mechanism in this dimension.

1.4 Profile

Unscored, and kept separate from every score on purpose. The profile records what a mechanism price cannot express: what a running program costs, how well a coding model and an agent work in the language, and whether a safety-critical path exists.

1.4.1 Energy and cost

What this axis asks: what does a running program cost in energy and time?

  • ✅ Compiles to native code: the fastest class in the language energy and time benchmarks [5], [6]. A causal re-analysis attributes the difference to execution time [7].

1.4.2 AI and agent readiness

What this axis asks: how well does a coding model and an agent work in this language?

  • ✅ A large training corpus and strong code-generation results: models write this language well [8], [9].

1.4.3 Safety certification

What this axis asks: is there a certified or standards-qualified path to a safety-critical system?

  • ✅ A standards-qualified toolchain or an established safety standard covers this language.

1.5 Scoring detail

1.5.1 Core coupling Dimensions

Dimension Mechanism Description Present Cost
Type T1 dynamic no static check — 0
T2 weak static ✅ −8
T3 dynamic/duck dispatch — 0
T4 no sum types — 0
T5 no generics — 0
T6 no namespaces — 0
T7 type erasure/reflection — 0
T8 operator overloading ✅ −4
T9 inheritance required for polymorphism — 0
T10 no null-safety ✅ −8
T11 no module boundary — 0
T12 no effect tracking ✅ −8
T13 async/sync colouring — 0
T14 unchecked foreign boundary ✅ −4
Type subtotal −15 (−32)
Construction C1 global mutable state by default — 0
C2 no immutability by default ✅ −4
C3 constructors coupled to allocation — 0
C4 no constructor/validation — 0
Construction subtotal −4
Memory M1 manual deallocation — 0
M2 GC non-deterministic pauses — 0
M3 no RAII — 0
M4 no ownership model ✅ −8
Memory subtotal −8
Error Er1 no structured path — 0
Er2 unchecked exceptions only ✅ −8
Er3 errors ignored/non-exhaustive — 0
Er4 no composable result type — 0
Error subtotal −8
Concurrency K1 GIL/no parallel — 0
K2 shared mutable state default ✅ −8
K3 manual sync no race detection ✅ −8
K4 no structured concurrency — 0
K5 no primitives — 0
Concurrency subtotal −15 (−16)
Platform P1 cannot function outside one vendor/domain — 0
P2 single-vendor but other uses — 0
P3 legacy/discontinued platform — 0
Platform subtotal 0

Core Dimensions score: 50/100 — total cost = −50 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

1.5.2 Ecosystem coupling Dimensions

Dimension Mechanism Description Present Cost
Performance R1 interpreted no AOT/JIT — 0
R2 GC pauses — 0
R3 JIT warmup — 0
Performance subtotal 0
Ecosystem Ec1 no package manager ✅ −4
Ec2 fragmented tooling ✅ −8
Ec3 small/niche/discontinued — 0
Ec4 proprietary — 0
Ec5 platform-locked tooling — 0
Ec6 monoculture — 0
Ec7 legacy burden — 0
Ecosystem subtotal −12
Evolution V1 breaking changes — 0
V2 frozen — 0
V3 discontinued — 0
V4 glacial standards — 0
Evolution subtotal 0
Domain D1 domain/vendor lock-in — 0
D2 poor domain fit — 0
D3 framework forces architecture — 0
Domain subtotal 0
Learning L1 steep ✅ −8
L2 large surface/multi-paradigm ✅ −4
L3 sparse docs — 0
Learning subtotal −12
Syntax S1 verbose — 0
S2 inconsistent — 0
S3 punctuation-heavy — 0
Syntax subtotal 0
Testing G1 weak tooling — 0
G2 poor debugging — 0
G3 runtime-only errors — 0
Testing subtotal 0
Security Q1 memory-unsafe ✅ −15
Q2 dynamic/weak typing risk — 0
Q3 known vulnerability/injection — 0
Security subtotal −15

Meta Dimensions score: 61/100 — total cost = −39 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

1.5.3 Engineering readiness Dimensions

Dimension Mechanism Description Present Cost
Reproducibility Y1 build not reproducible ✅ −8
Y2 dependencies not pinned ✅ −8
Reproducibility subtotal −15 (−16)
Supply chain Y3 no signed provenance ✅ −8
Y4 registry without namespacing — 0
Supply chain subtotal −8
Observability Y5 no stable tracing standard — 0
Y6 no structured logging ✅ −4
Observability subtotal −4
Feedback Y7 slow build ✅ −8
Y8 no fast in-editor analysis — 0
Feedback subtotal −8
Interop Y9 no foreign-function interface — 0
Y10 no portable target — 0
Interop subtotal 0
Governance Y11 single-vendor governance — 0
Y12 closed specification — 0
Governance subtotal 0

Readiness Dimensions score: 65/100 — total cost = −35 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

Verdict: C++23 provides substantially better coupling than its reputation suggests. Modules decouple compilation units. std::expected provides composable error handling. Concepts eliminate template error message hell. std::span/std::mdspan provide safe non-owning views. Smart pointers are idiomatic and eliminate manual new/delete. Main strength: RAII + zero-cost abstractions + deterministic performance. Main weakness: the language retains unsafe escape hatches (raw pointers, macros, exceptions) and new features coexist with old ones, meaning teams must enforce modern idiom discipline. C++23 with Core Guidelines and static analysis is a different language from C++98.


The formal development. The definitions, theorems, and proofs behind this page are published in:

All published papers

References

[1]
Y. Loth, “On the nature of coupling: All coupling as shared resource access.” Zenodo, Aug. 2026. doi: 10.5281/zenodo.21925122.
[2]
Y. Loth, “Coupling as a consequence of cohesion: Decomposition, the coupling floor, and domain-imposed coupling.” Zenodo, Aug. 2026. doi: 10.5281/zenodo.21925201.
[3]
Y. Loth, “On the nature of cohesion: Cohesion as correctness relative to a partitioning rule.” Zenodo, Jul. 2026. doi: 10.5281/zenodo.21703193.
[4]
ISO/IEC JTC 1/SC 22, “Programming languages — C++.” International Organization for Standardization; International Standard ISO/IEC 14882:2024 (C++23), Geneva, Switzerland, 2024.
[5]
R. Pereira et al., “Energy efficiency across programming languages: How do energy, time, and memory relate?” in Proceedings of the 10th ACM SIGPLAN international conference on software language engineering (SLE), 2017, pp. 256–267. doi: 10.1145/3136014.3136031.
[6]
R. Pereira et al., “Ranking programming languages by energy efficiency,” Science of Computer Programming, 2021, doi: 10.1016/j.scico.2021.102609.
[7]
N. van Kempen, H.-J. Kwon, D. T. Nguyen, and E. D. Berger, “It’s not easy being green: On the energy efficiency of programming languages,” in Proceedings of the 40th IEEE/ACM international conference on automated software engineering (ASE), 2025. doi: 10.1109/ASE63991.2025.00131.
[8]
S. Joel, J. J. Wu, and F. H. Fard, “A survey on LLM-based code generation for low-resource and domain-specific programming languages,” ACM Transactions on Software Engineering and Methodology, 2025, doi: 10.1145/3770084.
[9]
Y. Qing et al., “EffiBench-x: A multi-language benchmark for measuring efficiency of LLM-generated code,” in Advances in neural information processing systems 38 (NeurIPS), datasets and benchmarks track, 2025. doi: 10.48550/arXiv.2505.13004.