ADR-1003: Bump project-wide C++ standard from c++11 to c++23¶
- Status: Accepted
- Date: 2026-06-04
- Deciders: lusoris
- Tags: build, c++, cpp23, meson, standards, fork-local, vmafx-rebrand
Context¶
core/meson.build has pinned cpp_std=c++11 since the initial fork divergence. ADR-0727 (Wave 2 of the C++ migration) documented the decision to bump the project-wide default to c++23 as part of that wave, but the core/meson.build change was never landed — the PR (#48) only delivered dict.cpp and the surrounding isolated-lib objects without updating the default_options entry.
Meanwhile, multiple source files have been converted from .c to .cpp and compiled under C++23 via per-target override_options: ['cpp_std=c++23']:
metadata_handler.cpp(ADR-0708, overridec++20)log.cpp,opt.cpp,fex_ctx_vector.cpp,picture_pool.cpp,gpu_picture_pool.cpp,gpu_dispatch_env.cpp,read_json_model.cpp(ADR-0708 wave / ADR-0768 / ADR-0858 / ADR-0761)feature_extractor.cpp,feature_collector.cpp,feature_name.cpp,cpu.cpp,ref.cpp,thread_locale.cpp,picture_copy.cpp,luminance_tools.cpp,psnr_tools.cpp,mkdirp.cpp,mem.cpp,model.cpp,output.cpp(subsequent Wave PRs)
The project default of c++11 is therefore inconsistent with the files already compiled at C++23. Any future .cpp file added directly to libvmaf_sources without its own override_options would silently fall back to C++11 and lose access to std::expected, std::string_view, CTAD, and structured bindings that existing C++ TUs rely on.
The CI toolchain (GCC 13+ / Clang 16+ minimum per ADR-0692 context, dev machine on GCC 16 / Clang 22) fully supports C++23.
Decision¶
Set cpp_std=c++23 in core/meson.build default_options. The existing per-target override_options: ['cpp_std=c++23'] on the isolated static libs become redundant but are left in place — cleanup is deferred to a follow-up sweep PR to keep this PR minimal and reviewable.
Also fix core/test/meson.build: test_feature_collector_coverage referenced internal non-static helpers from feature_collector.cpp but only linked against libvmaf (which includes the C version feature_collector.c where those helpers are static). The binary was link-failing since it was introduced. Fix: compile feature_collector.cpp directly into the test executable (same pattern as test_predict).
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
Keep c++11 project default and always use per-target override_options | No change to default | Every new .cpp file must remember the boilerplate or silently compiles at C++11; inconsistent with already-present Wave 1–9 files | Fragile; undocumented footgun for contributors |
Bump to c++20 instead of c++23 | Wider legacy toolchain support | std::expected (used in dict.cpp) requires C++23; fork already targets C++23 per ADR-0727 decision | ADR-0727 decision already mandated C++23 |
Bump and immediately remove all per-target override_options | Maximally clean build | Large diff; harder to bisect; MSVC token (vc++latest) still needed for isolated libs pending MSVC C++23 support validation | Defer cleanup; minimal diff is safer first |
Consequences¶
- Positive: Any new
.cppadded directly tolibvmaf_sourcescompiles at C++23 by default; no boilerplate needed. Build is internally consistent.test_feature_collector_coveragelinks correctly (pre-existing broken link now fixed). - Negative: Build toolchain floor rises to gcc >= 13 / clang >= 16 for C++ (unchanged from the Wave 1 precedent; C++ was already at this floor via per-target overrides). External builds on Ubuntu 20.04 LTS (gcc 9) must use the container image.
- Neutral / follow-ups:
- Sweep PR to remove now-redundant
override_options: ['cpp_std=c++23']from the isolated static libs (exceptmetadata_handler_cpp20_libwhich uses C++20 intentionally, and the MSVC-pathvc++latestlibs). - Update
core/AGENTS.mdguidance to reflect that new.cppfiles no longer need isolated-lib boilerplate for C++23.
References¶
- ADR-0708 — C++23 pilot wave, established per-target pattern.
- ADR-0727 — Wave 2 decision to bump project
cpp_stdtoc++23; this ADR lands what ADR-0727 decided. - ADR-0692 — Bumped C standard to C23.
- ADR-0702 — Phase 4 language modernization policy.
- req: "core/meson.build pins cpp_std=c++11 but ADR-0708/0692 + the C++23 Wave PRs have already converted multiple files to .cpp with C++23 expectations. The c++11 pin is inconsistent."