ADR-0735: C++23 Wave 5 — cpu, ref, thread_locale¶
- Status: Accepted
- Date: 2026-05-28
- Deciders: lusoris
- Tags:
build,c++,cpp23,refactor,internals,fork-local
Context¶
The ADR-0708 playbook established the pattern for incrementally converting core/src/*.c files to C++23: rename to .cpp, wrap in an isolated static_library with override_options: ['cpp_std=c++23'], preserve the public C ABI via extern "C" in the header, and apply real C++23 idioms rather than mechanical renames.
Wave 5 continues that migration with three small files selected by LOC (smallest first) that have no conflicts with the in-flight Vulkan-drop branch (#47):
-
cpu.c(55 LOC): The global CPU-flag state variables are converted from barestatic unsignedtostd::atomic<unsigned>. This eliminates a potential data race whenvmaf_init_cpu()andvmaf_get_cpu_flags()are called from different threads during initialisation, which POSIX permits oncepthread_onceorstd::call_onceis in play on the caller side.memory_order_relaxedpreserves near-zero overhead on the hot read path. -
ref.c(54 LOC):vmaf_ref_initusedmalloc+memset+atomic_init. Replacing withstd::make_unique<VmafRef>()value- initialises the struct (eliminating thememset) and makes the early- return error paths leak-safe without any explicitfree().release()transfers ownership to the raw*refpointer returned to callers.vmaf_ref_closeusesdeleteinstead offreebecause the object was allocated byoperator newviamake_unique. Theextern "C"function declarations were also added toref.h, which was the only internal header missing them. -
thread_locale.c(132 LOC): The platform-specific teardown ladder (POSIXuselocale/freelocalevs Windows_configthreadlocale) is encapsulated inVmafThreadLocaleState's destructor, replacing three explicitfree(state)calls scattered across error-return paths invmaf_thread_locale_push_c.vmaf_thread_locale_popis reduced to a one-liner: adopt the raw pointer into astd::unique_ptrand let the destructor run.std::array<char, 256>replaces the Cchar old_locale[256]on Windows for bounds-safe initialisation.
Decision¶
Convert cpu.c, ref.c, and thread_locale.c to .cpp with C++23 idioms. Each is compiled as an isolated static_library with override_options: ['cpp_std=c++23'] and linked into libvmaf.so via extract_all_objects. The public C ABI is preserved unchanged.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
Keep as .c, apply fixes in C | Zero build-system churn | Cannot use std::atomic, make_unique, RAII destructors in C; fixes would require C11 atomics (_Atomic) and explicit cleanup patterns that are less expressive | The goal is language modernisation, not a C-dialect band-aid |
Single monolithic cpp_std=c++23 override on the whole libvmaf target | Simpler meson.build | Risks compile failures on C TUs that mix C and C++ token rules; propagates c++23 to many files not yet reviewed | ADR-0708 established the per-file isolation pattern precisely to avoid this; Wave N converts files incrementally |
| Convert all three into one combined TU | One static lib | Loss of per-file blame history, harder to review, harder to bisect | Per-file conversion matches the Wave playbook |
Consequences¶
- Positive: Three more files carry thread-safe atomics and RAII lifetime management.
vmaf_ref_closenow usesdelete(correct formake_unique-allocated objects) instead offree. The teardown logic inthread_localeis encapsulated and cannot be accidentally bypassed by future early returns. - Negative: Three new isolated static libs add minor build-graph overhead (three extra Meson targets).
- Neutral / follow-ups:
ref.hnow hasextern "C"guards, which is the correct state for any header consumed by both C and C++ TUs. The C++ standard guaranteesstd::atomic<unsigned>has the same storage layout asunsigned(same size, alignment) so the ABI of any struct that embeds CPU flags is unchanged.
References¶
- ADR-0708 — original C++20/23 migration playbook.
- Waves 1–4:
metadata_handler.cpp(0708), plus the files listed in PR context for Waves 1–4. - req: "pick 2-3 more small core/src/*.c files not yet in flight, convert to .cpp with real C++23 idioms" (user Wave-5 dispatch message, 2026-05-28).