C++26 is finally locked in, and it brings reflection, contracts, better memory safety, and a new async/concurrency model into one standard draft.
Ellen
C++26 is finally locked in, and it brings reflection, contracts, better memory safety, and a new async/concurrency model into one standard draft.
Ellen
“Enhances memory safety without requiring code rewrites” is doing a lot of marketing work there. In C++ land, anything that doesn’t require rewrites usually means “we added a knob, ” and then everyone argues about whether to turn it on because it breaks someone’s build from 2013. On contracts: my read is it’s closer to “asserts but standardized” than “always-on runtime invariant system, ” mostly because the moment you say “enabled in release, ” people start asking about cost, UB interaction, and whether the optimizer is allowed to assume the contract. Teams can choose to keep checks in release, but I wouldn’t expect that to be the default posture across toolchains. Tiny sketch of the vibe (not exact final syntax, but the intent):
int div(int a, int b)
[[pre: b != 0]]
[[post: _return == a / b]]
{
return a / b;
}
If compilers treat [[pre:. . . ]] as something they can assume (even when not checking), you get “safety” only if you’re disciplined. If they treat it as “must check, ” you get safety, but you’ll feel it in perf and in how much legacy code suddenly starts yelling at you. Curious: are you thinking about this for a greenfield codebase, or trying to retrofit a big existing one? That changes whether “opt-in annotations” is a non-starter or just Tuesday.
“Enhances memory safety without requiring code rewrites” reads like “we shipped a static analysis mode and a pile of annotations” (which is still useful, just… not magic), and your point about contracts turning into optimizer assumptions is the bit that gets me. If contracts can be compiled out but still assumed, you’ve basically standardised a new way to write down UB with nicer syntax, so what’s the story on tooling here—do you reckon compilers will treat contract violations as “diagnostic + terminate” by default, or are we heading straight back to the old NDEBUG shrug?
“Diagnostic + terminate” feels like the only default that won’t quietly train people into footguns again, but I honestly don’t know if the committee/toolchain folks will stomach that for existing codebases. The part I’m watching is whether contracts get a third “audit” kind of build mode in practice: always evaluate, cheap handler (log/abort), and crucially not treated as optimizer assumptions unless you explicitly ask for it. Do you know if the current draft lets you say “this contract is never an assumption” in a portable way? not sure about that detail.
:: Copyright KIRUPA 2024 //--