C++26: Reflection, Memory Safety, Contracts, and a New Async Model
Posted by Akkeri@reddit | programming | View on Reddit | 62 comments
Posted by Akkeri@reddit | programming | View on Reddit | 62 comments
Dean_Roddey@reddit
So much effort for a language that already owns a condo in Florida. Though obviously there's a lot of legacy C++ code bases out there, how many of them are really going to go all in on all this stuff? How many of them are even up to C++/20?
It's fine to add incremental safety features to help make those legacy code bases safer within the limits of changes that legacy code bases are willing to absorb. And that's where the effort should be concentrated. But, beyond that, everyone should be moving away from C++ wherever possible, and adding big new features on top of an already shaky foundation just seems counter-productive.
I mean I was a hard core C++ developer for three decades, but it's time to move on. It's seriously old technology and we owe the users of the products we create better.
joashua99@reddit
Once again, with enough time, every language slowly becomes Java.
kiteboarderni@reddit
Downvoted for speaking the truth. Copied the concurrecy api too when cpp did a refresh.
Schmittfried@reddit
Java is not the only language with reflection and if anything, Java is finally (but slowly and often in a mediocre way) copying features from more modern languages.
kiteboarderni@reddit
Of course it's not....but cpp is copying java in multiple ways. Not only reflection.
Schmittfried@reddit
Only if you consider Java a seemingly mindless amalgamation of strangely implemented features. Which in some instances is fair, but despite my passionate grudge against it I‘d say Java is much more well-designed and consistent than C++.
JuanAG@reddit
The same contracts that were (or are) still broken?
Last new i got was that contracts are per TU (not exactly a file but close enough) meaning that contract in one TU/file will behave one way and in another when it is in other TU/file. The big issue is that you cant control that since the compiler can inline code moving from the proper TU to another and the contract never triggering there when you think it will, classic C++ feature style, something good half broken, as always
Madsy9@reddit
Yeah, I don't understand the motivation behind contracts either. Why bother with them when they're just souped up runtime assertions, and not even good at that? There is already support for that via assert() and exceptions. What would be useful is compile-time contracts like what Whiley and F* has, verified by a SAT or SMT solver. Or being able to write proofs for types like in Agda, Idris and Lean. Apparently C++ contracts is for something else than verification, but what exactly?
StardustGogeta@reddit
The paper that talks about the rationale is available at this link.
Your mileage may vary, but I've read a tiny bit of it, and what I did read was (in my opinion) rather unconvincing.
On page 6, the list of priorities they give seems almost inverted to how I would have preferred such a feature to be designed/implemented. They explicitly deprioritize the use of contracts for things like formal verification, compiler optimization, and static analysis in favor of documentation and runtime checking... But decent solutions for documentation and runtime checking already exist!
Their stance seems to be "get something out now and we can fix it later," but I just don't buy it. I don't think it needs to be perfect, but it needs to be useful, enough that I would deliberately opt in to using it. As it stands, it's nowhere near that point.
I mean, things like contract assertions having side-effects? Come on. With foot-guns like that, even if I understood what I was writing, my coworkers would kill me if I started using that in my code.
Schmittfried@reddit
I don’t get your problem, that’s totally in-theme for C++.
Maybe-monad@reddit
Does it solve any problems or is just another bump in complexity?
Murky-Relation481@reddit
I know this is an unpopular opinion but it feels like people who think this have never actually used C++ for anything serious. You can use a minimal set of modern C++11 features and never look forward or back and write perfectly reasonable code. Almost everything added since 11 and I would argue even more so after 14 and 17 is entirely optional knowledge to write "good" code. Almost everything else is a tool that can help you do things more simply if you learn the complexity upfront but doesn't actually prevent you from doing things well or enough to get the job done.
funkmasterhexbyte@reddit
I was a C++ readability reviewer at Google for 5 years. Google follows a "live-at-head" approach (see: https://abseil.io/about/compatibility) for C++, meaning they always (try to) use the latest features and compiler. When I left in 2021, for example, they had just started supporting and encouraging Designated initializer lists which was a C++20 feature.
So, yes, I've used C++ for something serious.
Murky-Relation481@reddit
Simply and safely, probably not. Safely? Yes. There was nothing in the standards that's explicitly unsafe if used correctly, which is sort of what I am getting at. The vast majority of safety came in 11 when we got library components that instilled memory safety as a type vs. raw pointers.
I'd argue the rest is design safety which is not necessarily a language feature.
vanderZwan@reddit
Watch out, if Don Norman hears you saying stuff like that that he'll hunt you down and slap you in the face with a hardcover copy of "The Design of Everyday Things".
light_oxygen@reddit
Hehe, Try doing Concepts in C++11.
You've never used C++ for anything serious. Serious people have been updating their libraries to the latest standard since forever and especially since 2011.
Every "Modern C++11 library for such such" is now "Modern C++20/23...". Soon it'll be C++26.
azswcowboy@reddit
Utter nonsense. Newer standards versions will in fact compile your code to faster executable with no changes (mandatory copy elision in c++17). Range based for loops make code simpler and more correct. Concepts and coroutines aren’t optional features for many applications. Having built in standard library hardening that’s portable instead of per compiler and with lots of flag fun isn’t acceptable now. There’s dozens of features that make routine coding simpler and better in newer standards. And your old code will work fine. Your opinion isn’t unpopular, just wrong. There’s plenty of talks that cover the features on YouTube - it doesn’t take to learn. Not that if you upgrade to a more recent compiler you’re going to get a newer base version already.
Maybe-monad@reddit
Is this C++26 reflection in action?
That means you don't have to bother learning anything new, just upgrade the compiler.
But it makes it break in unexpected ways too.
Why would I want to deal with extra complexity, weird edge cases and lack of universal compiler support when libuv is here and it works?
azswcowboy@reddit
Also fixed in c++26. And very much a corner case. And corner cases clearly don’t exist in all languages 🙄. Anyway, I didn’t say it was perfect, just better.
We’re discussing c++, not Python. But please, feel free to use Python.
Maybe-monad@reddit
libuv is a C library used C++ projects like node. Are you C++ programmer or just a good pretender?
azswcowboy@reddit
Sorry I thought you were discussing this
https://pypi.org/project/uv/
My bad. And no I’m not familiar with libuv.
I’m going to stop responding to you now to save you from the continued down votes. Good luck.
dukey@reddit
I mean you are right. Personally I could never go back to writing say c++ 98. But I've gone through most of the versions and learnt the new features as they came out. Today the language is so massive it's verging on ridiculous. I mean, how many different ways can you init a variable in c++? Whilst new features simplify stuff most c++ code bases will have large amounts of legacy code that you still need to know how to deal with. So the cognitive load only increases. This is probably why C is still so popular.
azswcowboy@reddit
This isn’t my experience. We don’t use any of the old ways in our codebase. So cognitive overload is massively reduced because the new ways are simply easier. Like writing a for loop. I always write range-for loops - to the point that Ive forgotten how to write indexed loops. We use std::format everywhere. Sure iostreams are there, but they don’t occupy mental space because it’s rare to see in our code. The fact that I can write
And it does the obviously correct thing eliminates a loop and saves cognitive overload. Also I don’t need a c++ expert to do that bc it’s basically like python - everyone gets it instantly.
dukey@reddit
>to the point that Ive forgotten how to write indexed loops.
And there it is. And honestly there is nothing wrong with that. Most people or teams probably only use a subsection of the language anyway. The problem comes when people have to interact with other code outside of their box, and with c++ this box has grown to become very large.
Murky-Relation481@reddit
Please explain how that is true. That is like saying no one could write TMP or use async paradigms before C++20, which is absolutely not true.
I think you wildly missed my point. All of those things are great, I've written thousands of lines of C++23 in the last few months, but I could have written all of that stuff 10 years ago too, it'd just look different, might be more verbose, and the compiled code might not be as fast, but its not like it prevented functionality if I wrote it in C++14 rather than C++23.
My entire point is you can pick and choose what new features after C++11 you want to use, it's not a "YOU HAVE TO KNOW EVERY NEW THING OR YOU'LL BE INCAPABLE OF PROGRAMMING" like so many doomsayers always seem to bring up in regards to any new version of the standard.
Maybe-monad@reddit
He misses all points that aren't an opportunity to evangelize modern C++
azswcowboy@reddit
I think you’re right, we’re wildly in agreement - thx for clarifying! The thing about concepts and coroutines however is that the earlier stand ins were inferior in so many dimensions that it’s difficult to consider it the same in my book. Concepts goes all the way back to the 90’s, but having a built in way instead of meta programming hacks eases the burdens, improves compile times and errors, etc.
So yes, my point was you can suffer with the past or come to a better world. And you can do it at your own pace.
Mognakor@reddit
IIRC you could rewrite the Qt MOC (Meta Object Compiler) via reflection. Also use compiletime reflection to generate runtime reflection methods etc.
It should result in a reduction in complexity at least for library consumers.
dsffff22@reddit
It's insufficient for QT MOC While there are some talented people working on reflection I'm slightly baffled how they didn't set mandatory MVP goals, like a serialization library, partial replication of MOC and other 'essentials' in 2026 with acceptable compile times.
azswcowboy@reddit
The QT people were involved. Look carefully at what it says:
might. They certainly achieved partial replication — I don’t know that they’ve fully decided if they need token injection or not at this stage. Reflection is already a large feature, trying to jam more into it to achieve a particularly arbitrary goal doesn’t make sense. They absolutely had MVP goals and serialization most certainly is covered - noting that there are already several demonstrations that work with existing c++ serialization libraries. So far compile times have been fine, but it’s early days.
dsffff22@reddit
'Might' is not an acceptable state for such fundamental libraries/language features, because you easily standardize things which might not work as well as planned for those complex features. If Serialization was covered by the MVP goal then where's the libraries and the benchmarks for It? The same goes for the rest of your claims.
azswcowboy@reddit
Might is absolutely fine because the more advanced capabilities build on this core. As for backing up claims I suggest searching /r/cpp for discussions. But here’s one:
https://lemire.me/blog/2024/08/13/reflection-based-json-in-c-at-gigabytes-per-second/
Note the date on the post - he’s working with preproduction compilers. And the important point is that the simdjson core doesn’t need to change. Reflection just supercharges it.
dsffff22@reddit
'Might' is one reason for technical debt with standardization. Also, If you make claims you should provide sources for that It's not on me to search a Subreddit. The blog post is mostly irrelevant for real world scenarios as the priority is being flexible first and then being fast, among those flexible requirements are custom de/serialization hooks, renaming of fields and dynamic dispatch scenarios. It doesn't really help you If you can de/serialize in C++, but you can't consume/produce at/from the other side due to lacking flexibility. If you'd actually follow the reflection story you'd rather link Barry's blog article which gets pretty close to a real world application scenario, but afaik there's no such complete library with performance numbers yet. There was also another blog post I remember which showed pretty bad performance results for reflection.
azswcowboy@reddit
I assure you I have. There’s dozens of posts that could be here. I gave you one. And yes, I’m telling you that if you want to know the details go search for yourself, you seem capable. I’m here responding to a super surface level article that’s incomplete to misleading. You’re here throwing FUD on the entire enterprise - so be it.
It’s json? I think it’ll be fine to consume from any language.
I made no claims - as I said early days.
It’s Reddit, I’m here saying what’s happening and sharing my opinions - take it fwiw. It’s easy to make doomer claims, like your doing, that have no bearing in reality.
This thread is now well past productive discussion.
funkmasterhexbyte@reddit
Reflection will solve problems with code generation. It will be best for reducing complexity/verbosity/undefined behavior.
case-o-nuts@reddit
I would rather just generate code, honestly.
Full-Spectral@reddit
Yeh, I use Rust, but I have my own code generator for things a lot of folks would use proc macros for. It significantly reduces build overhead in large systems, and you can debug the generated code.
funkmasterhexbyte@reddit
haven't read anything on it yet, but I remember Herb's talk from a few years ago it showed really debugging on a custom godbolt compiler!
Maybe-monad@reddit
Wrong, complexity is moved in the compiler, verbosity is reduced at the cost of compile times and undefined behavior is still there.
Undefined behavior exists at the specification level where the behavior of a compiler isn't fully known, when you compile with version X of clang or gcc that isn't a problem
funkmasterhexbyte@reddit
Nothing I said was wrong.
Leaving aside your nasty Sheldon-from-Big-Bang-Theory aside, whether you personally think that the cost is worthwhile is irrelevant to the discussion. I don't really feel like having that discussion with you, though, because you seem like a douche judging from your "Sheldon" impression.
Maybe-monad@reddit
If you don't account for the programming language complexity, which in this case means another feature with plenty of edge cases that interacts with many others with their own weird edge cases.
Undefined behavior is an overloaded term for a problem most people fundamentally misunderstand, just like you misunderstand that having a code generator in a compiler doesn't make the code less UB prone than having the code generator run separately or having the user write the code.
It's only natural to be annoyed by the ignorance showed here, if you feel targeted it's fine, you have a chance to address the problem but you won't because it's easier to disregard and put yourself on a pedestal.
funkmasterhexbyte@reddit
That already exists today. They're called code generators. They have no standard, and they each have their own unique slew of bugs and edge cases. Reflection will consolidate those problems into one rigorously-tested system.
That's a cute attempt, but I do know what I'm talking about. 🤭
Maybe-monad@reddit
Downvotes without replies?! I thought reddit is supposed to provide entertainment in the form of logical fallacies just the C++ standards committee is supposed to be unable to design a language or understand programming.
dsffff22@reddit
I'll believe It once I see It, protocol buffers provide interoperability between many different languages, so C++ essentially would have to either parse .proto files at compile time or generate those via reflection and the matching code as well. I'm not exactly confident in the C++ compiler to be fast enough and cache reflection results sufficiently so that for large code bases using It, won't face a massive slow-down in compile time.
HighRelevancy@reddit
Oh look it's this comment again. 20 years strong, keep the fight going brother! /s
Jolly_Resolution_222@reddit
Source generators like C# would be the way.
azswcowboy@reddit
Much code will be simplified or eliminated. Any sort of serialization code can be automatically generated. There’s already experimental support in major libraries like simdjson for automating serialization. There’s dozens of other use cases for compile time programming.
Maybe-monad@reddit
Basically serde in C++
SuperV1234@reddit
Much better, because Rust doesn't even have reflection. With C++ you could get the functionality of Serde without having to mark any type on at its definition point.
Maybe-monad@reddit
Doesn't make any sense, the C++ reflection mechanism is advertised at compile time only, it can't get any more powerful than proc macros without than being not the case.
SuperV1234@reddit
It does make sense. You can reflect on any type, while proc macros generate code only for marked types.
Maybe-monad@reddit
That's a design decision with different tradeoffs not a more powerful model of computation
SuperV1234@reddit
No, it's a superset.
Maybe-monad@reddit
You frame it like a program running in Docker is a substet of the same program running on bare OS, nonsense
SuperV1234@reddit
The design of C++26 reflection can do everything that proc macros can do and more. It's really not that difficult to understand, but you do you -- feel free to die on this hill and stay ignorant.
Maybe-monad@reddit
That sounds like marketing, examples
_Noreturn@reddit
it simpkfies alot of things, and unexpectedly would actually make for better compile times.
azswcowboy@reddit
Well that’s a bit of simplification. GCC will indeed bring contracts and reflection to gcc16 which releases soon. Clang, while it has branches for these features might take longer. Reflection by itself depends on several other features like template-for (fully compile time for loop)
Nobody has implemented std::execution — although that’s a standard library feature — which has a couple implementations in the wild. Meanwhile the article misses linear algebra, simd, ranges parallel algorithms, and dozens of other standard library features. There’s a full list here of 186 individual adopted papers below - it’s a big release:
https://cppstat.com/
Of course the ink isn’t really dry for 26 to be the standard. The final working draft isn’t published and final national body votes to approve aren’t cast. This part is typically routine but for 23 it took over a year for the iso bureaucracy to churn. Still some big features will indeed be available to working programmers sooner than later.
zebullon@reddit
reflection does not depend on template for.
azswcowboy@reddit
Not directly, but many practical applications would be much more difficult without it.
vanderZwan@reddit
I'm not really interested in writing C++ directly if I don't have to, but I have played around with https://github.com/hsutter/cppfront for a personal side-project to try some simple SIMD experiments, and found it a surprisingly pleasant experience (I might try to do some creative coding in it if I get it to play nicely with OpenFrameworks). A lot of the new features of C++26 therefore have me "indirectly" excited since they probably will drive that project forward too.
daniel_eve_10@reddit
Wow, C++26 sounds wild. I'm still trying to wrap my head around some of the C++20 features tbh. Memory safety's always a good direction, so that's cool. Async updates? Should be interesting. I'll stick with my current projects though!