Trip report: November 2025 ISO C++ standards meeting (Kona, USA)
5 points by jmillikin
5 points by jmillikin
I am very disappointed to see contracts are in. It’s a very clear signal about the long-term direction of the language away from compostable features, and away from enabling source-level reasoning. From C++26 onwards, I no longer recommend C++ for any security or safety-critical systems, even on CHERI platforms, if you do not have complete control over all code in your codebase (including maintaining your own standard library).
C++26 will be a gift for two groups:
This response surprises me. What part of contracts adds new attack vectors?
C++ has a notion of inline functions, where they are compiled in each compilation unit and then, when linked together, the linker picks one. The linker's selection is somewhat arbitrary, but tends to be deterministic.
C++ says it's undefined behaviour to link two versions of the function if their text (sequence of tokens) differs. This is the one definition rule (ODR). It turns out that this isn't quite enough to be sound and there are some compiler bugs that mean a version compiled in one compilation unit will be subject to some analysis that won't be true for another. I would like to see C++ work towards addressing this because it means that you cannot really reason about the semantics of a C++ compilation unit by reading just the text in that compilation unit even if it doesn't call any functions that are not defined in that compilation unit.
C++ contracts make it possible, via compiler switches, to disable or alter the semantics of things in these functions. Any optimisation that arises from interprocedural analysis may be unsound as a result. I had a little PoC that resulted in miscompilations, the GCC folks agreed it was a bug and fixed that specific instance, but this is going to be a thing where either you can't do any IPA across functions that use contracts (which will hurt performance), or you run the risk of unsound optimisation.
If you want to do a supply-chain attack, three independent commits that modify an inline function in a header, modify the contracts compiler flags in the library, and modify the contracts compiler flags in a program that imports it, each of the patches can be correct in isolation, but will lead to specific miscompilations in combination. Anyone doing an audit of the changes, or of the library, will see nothing malicious.
What do you think of Herb's Sutter opinion on this ? It doesn't seem to be really worried about it in long term. (His talk: https://youtu.be/oitYvDe4nps?t=1810)
I don't click on YouTube links, sorry.
EDIT: I also can't comment much on most of the things Herb has said about contracts without breaking confidentiality rules.
If you just object to link (which is understandable) and not to youtube itself, here is the title : "The Joy of C++26 Contracts - Myths, Misconceptions & Defensive Programming - Herb Sutter" published on cppcon account. The discussion about ODR start at 30mn.
Thanks. The discussion of ODR on NDEBUG is the reason why sensible libraries don't use NDEBUG and use a per-library thing. We learned that this was a problem. So contracts have... a single global toggle (there is a follow-on thing that promises to make this per-component in a backwards-compatible way.
'There's no linker feature... yet.' Okay, but can you move to using a new linker feature without recompiling the world? I believe that will be an ABI break, I am told it is not, but by people who have not even sketched out what the new model would look like, and who have never worked on linkers.
The example from P3835 is glossed over by saying 'it's not an ODR violation and you don't hit the problems with ORD because we claim that it's fine'. There is no systematic mechanism for describing how to implement this. The existing clang and GCC implementations do allow this mixing, as he asserts, but then some optimisations are not sound. And that's in a way that is unlike anything in other languages, including old C++, so if you want to do sound interprocedural analysis you will need to define new IR constructs. It will happen to work in some examples, possibly even a lot of examples. It took me about half an hour to come up with a simple example that the existing GCC implementation miscompiled when I tried. And I am not an exploit writer, or even someone who does a lot of red teaming.
All in all, this talk sounds like what I've been hearing from contracts advocates for a while. Dismissing concerns, claiming that problems are fixed when the current implementations have them, and then saying that it's all implementation defined and so if you have a problem it's an issue with the implementation not the standard, all without having any idea how to provide a generic solution to those problems. The thing I care about is that I can read some source code and reason about the behaviour of it. Herb says 'read your compiler documentation to see what is expected to work'. But then he also says that some of us write code for five platforms. I don't want platform-independent C++ to have semantics that I can't understand without reading the documentation for every compiler that might, at some future point, be used to compile my code. I want it to be defined in the standard because that is the point of having a standard.
I stopped watching at the next part where he gets onto the next trope of 'yes, P2900 is awful, but it's an MVP. Please ignore the fact that it's not minimal (it's huge) and it's not viable (it doesn't solve most of the problems contracts are intended to solve), but we will fix everything in future versions, and we promise that it will be ABI backwards-compatible, although we haven't actually sketched out how the new features will be lowered to the MVP ABI(s)'.
Thank you for taking the time to write this out.
Did you publish this proof of concept GCC miscompilation anywhere?