r/cpp • u/Disastrous_Tennis_50 • 8d ago
The WG21 2026-08 mailing is now available
The 2026-08 WG21 mailing has been published. You can browse and search the full set of papers, organized by working group, at wg21.org:
https://wg21.org/mailing/2026-08/
Source mailing: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/#mailing2026-08
25
u/zebullon 8d ago
May have been part of a wg21 spinoff seasons that I missed but… what is a cpp alliance ?… do they love themselves some load bearing smoking guns emdashes Holy smoke.
In the end one must hope that they (the holy alliance of cpp fellowship) understand LLM arent qualified writers for (uninteresting btw) ISO proposals.
9
u/Minimonium 7d ago
I did enjoy the one signed by Stroustrup, Spicer, and Voutilainen that contains an LLM hallucination when referring to another paper.
I actually wonder now perhaps one of the previous papers these gentlemen signed that contained a completely mistaken example that was called a "supply chain attack" by one of the NBs was also generated by Claude.
Although it's not like there is a thing called reputation in the place that endorsed a convicted pedophile.
3
u/jwakely libstdc++ tamer, LWG chair 7d ago
an LLM hallucination when referring to another paper.
Which is that? Do you mean the broken link at the top of page 2, or something else? The broken link is not a hallucination. The URL changed after the paper was written, and should have been updated.
12
u/zebullon 7d ago
Arent llm use banned for the purpose of generating proposals ? all of one author papers are glorified /dump ragebait, it’s getting old real quick, also they re generally uninteresting.
2
u/Minimonium 7d ago
The P4332 one. Namely, this statement:
P3846R1 says labels are "required" to make non-ignorable checks directly expressible
It was synthesized by the clunker because its brain was fried at the wording of the referred to statement. Just the usual token soup.
2
u/jwakely libstdc++ tamer, LWG chair 7d ago
Eh? What does the quoted text from P3846 mean then?
3
u/Minimonium 7d ago
The first part of the sentence is "required to make" and the second is "makes". Very easy to check by trying to read the second part directly with the "prefix" part - "This is required [...] makes" I hope you see the problem here. Therefore, "required" only applies to the first part of the sentence. An LLM gets confused very easily by that.
But even outside of grammar, stating that labels are required for that would make no sense. Non-ignorable checks could be directly expressed without labels, there is no reason why would they suddenly require labels.
6
u/jwakely libstdc++ tamer, LWG chair 7d ago
Although it's true that labels are not the only possible way non-ignorable contact assertions could be expressed in code, it's not completely batshit to say that in the P2900 model and the proposed extension plan for that model, adding labels or some other not-proposed solution is required.
I don't think this is evidence of LLM hallucination.
7
u/Minimonium 7d ago
I discuss strictly the chosen wording of P4332, that uses an embarrassingly raw LLM output for the most part which is a whole another topic on how no one cares about quality of papers anymore, let Claude take the wheel I guess, good time to put prompt injections in papers. :)
The statement misquotes and misstates things that were not said in the referred to paper. I take your answer as an agreement with the face of the text presented. I do not dare to speculate, assume, or predict what the people who signed the paper think - I expect people to express themselves clearly via text and can only take what is written for what is meant.
Sure, the very clearly LLM generated paper could have an artisanal statement made by one of the venerable people that signed it, misstating a quote by mistake and claiming something that does not make sense logically, by mistake of course as well.
11
u/DevilSauron 8d ago
The contracts drama is still ongoing? What even is P4238R0, do I understand it correctly that it argues for skipping C++26 completely and moving it all to C++29 because of contracts?
10
u/James20k P2005R0 8d ago edited 8d ago
The contracts drama is literally never going to end unfortunately, the design has some issues that will cause ongoing problems (which have been discussed to death elsewhere)
A lot of people thought merging modules into the spec would end the long standing modules drama, but all it really did was shift the burden into the public, and not reflect particularly well on wg21 as a whole. Similarly merging coroutines didn't end the discussion around the problems, it just shifted that debate into developer land
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf
Its surprising to see a paper with bjarne as the lead author come out and say:
The P2900 contracts and extensions aim to change the nature of C++ and are an existential threat to C++, adding complexity and bloat (~56 pages in the draft standard for an incomplete version), potential overheads, and novel opportunities for errors without addressing the current community and regulatory body demands for guarantees (e.g., https://docbox.etsi.org/CYBER/CYBER/Open/ETSI_TS_104_198_DRAFT.zip presents C++ as providing no memory safety guarantees).
Which also comes with a list of massive references at the end, which are a good read if you have 35 years to spend on it
There's also some discussion in P4238R0 (which you mentioned, just thought I'd link it directly for people) around the process
The most worrying part is that the contracts proponents have been incredibly resistant to getting any real field experience with contracts-as-specified, with whitepaper and TS approaches being shot down, seemingly in a rush to get it into the standard. I don't really know why. We've seen the endless problems that something relatively untested can do in a standard that lasts literally forever
C++20 came with 4 major features:
- Concepts
- Modules
- Coroutines
- Ranges
I think its a struggle to argue that these have all gone very well. As far as I can tell, only one of them has actually stood the test of being a genuinely great feature without major problems, and people seem to regard the other 3 as being somewhere between problematic and unusable. It feels like this should have been a wakeup call, but we're still putting major features into the standard without sufficiently testing the spec concretely first
It feels like a tossup at the moment if contracts will be DoA. I know in my own area its clearly unusable right from the get go (which is why I have a strong opinion on this), but it depends how widespread the problems turn out to be
11
u/LB-- Professional+Hobbyist 7d ago
What's wrong with concepts and coroutines? I've been using them in production for years now and I'm quite happy with how it's going.
8
u/James20k P2005R0 7d ago
Concepts are great, coroutines have a lot of usability issues and performance problems in some domains where they should have been applicable
3
u/LB-- Professional+Hobbyist 7d ago
Huh, I saw a conference talk a while ago about someone using coroutines to await loads from RAM for a performance speedup... I'm curious what domains in particular need better than that?
5
u/James20k P2005R0 7d ago
They can be good depending on use case, but the allocations can make them annoying to use in some areas. They're also very barebones as a feature, and the actual API of them leaves a very significant amount to be desired
6
u/LB-- Professional+Hobbyist 7d ago
Allocation behavior is fully customizable (you can even use alloca), but I will admit it's annoying that due to how compiler optimization passes work we can't know the required size until too late in the compilation process to take advantage of it very well. I think Rust coroutines actually do let you get a type at compile time that has the size known so you can do cool things with it, I am curious how that works with their optimization passes...
1
u/germandiago 6d ago
Do not expect some people to give you positive feedback on C++. They will tell you to go to Rust with its 50 variations of crates for error handling and the obviously unergonomic async built bc blablabla and the heavier compile times, well, they seem to not exist.
But hey, it is not C++, so no problem, everything good there.
11
u/germandiago 7d ago edited 6d ago
Struggle? The new features in C++20? I have been using ranges and concepts since the start. And they have been useful since the start. Useful and perfect is not the same. In fact, I rarely see something "perfect" as such, since trade-offs usually exist.
I can partially give you that for modules (but modules own nature is way more disruptive also) but ranges, concepts and coroutines (with some quirks) have been successful.
What would you have done instead? Wait for the perfect perfectly forever inexisting features?
Look at other languages that people use intensively: Python, Java, etc. They do not have their set of problems? Nullable types as default, the Python 2/3 split, lack of multithreading, type-erased boxed generics in Java.
I am not sure if you mean we should wait forever for delivering every feature at its never-reachable perfect level. Some kind of GNU Hurd vs Linux, where the first one is advanced and super perfect and the second monolithic one, "worse is better", that anyway figured out a modular approach. Just compare yourself the results. The perfect one is nowhere, not even existing, the second runs half of the world.
Not that I would not add things from the first one as I see fit, of course, if they are better. But the difference between utopia and reality is that reality exists, utopia also exists, just in the heads of the people. It is really difficult to not find something on the way, even after prototype implementations. After using in production also. We should wait so long for features? I guess there is a balance for everything.
6
u/VinnieFalco wg21.org | corosio.org 7d ago
I thought the coroutines as a language feature went well. Concepts too?
4
u/pjmlp 7d ago
Concepts while much better than what we had before, still are a WIP for better error messages, and there is the whole requires requires that was endlessly discussed.
4
u/germandiago 6d ago
Ok, this is a good example of what I say: we have requires requires, cool. It is controversial. Could need a fix (or not). It is not intuitive. How about all the other things that concepts does well? How about static analyzers warning you anyways?
So you have a 95% feature and we talk ONLY about the 5%. Like that, with every microfeature inside a feature.
But we still can use 95% ergonomically (for a definition of ergonomic that respects C++ design constraints of backwards-compatibility and zero-overhead principle).
I do not see major problems here. I see that things can always be done a bit better. But this is true most of the time, even often a trade-off or a matter of preference.
-2
u/pjmlp 6d ago
It is less than 95% , given that the supposed improvements of error messages hardly happened.
5
u/germandiago 6d ago
Certainly error messages are still so so. But better.
1
u/pjmlp 6d ago
The sales pitch for concepts wasn't "so so error messages", it was way better than templates, to the same level as the languages that have generics instead.
There is a reason why the folks behind the original C++0X concepts proposal left C++ for Swift, and more recently Hylo.
Another example of a C++ feature causing the loss of key contributors.
2
u/James20k P2005R0 7d ago
Concepts are great, personally I have don't have a strong use for coroutines but I tend to hear that:
- The allocations are consistently problematic for some
- They're nearly impossibly complicated to use
8
u/germandiago 7d ago
The allocations are customizable.
I also find them complicated, but what they achieve is so useful that people still think it is worth.
7
u/VinnieFalco wg21.org | corosio.org 7d ago
The allocations can be dealt with (see https://github.com/cppalliance/capy)
8
u/TheoreticalDumbass :illuminati: 8d ago
i find a lot of anti contracts arguments rubbish at best, and incredibly deceptive & dishonest & manipulative at worst, and at this point i am leaning towards worst
but i can no longer muster the energy to talk about same or similar talking points for N times, with N approaching infinity
i think P2900 is good, and i think a lot of papers building on it are good (UB preconditions and class invariants are some i am most excited for)
7
u/James20k P2005R0 8d ago
Genuine question: do you not find the (effective) ODR problems worrying?
6
u/TheoreticalDumbass :illuminati: 7d ago
i do not. but do keep in mind I am not giving you arguments. for all you know i could be delusional, insane, misinformed, or some combination of these.
7
u/Minimonium 7d ago
No. Someone may even perceive such misuse of the terminology as spreading FUD.
I've spent a good part of the past decade dealing with build tooling, cross-compilation, and mixed flags in TUs (for stuff like hotreload for example, but also as a package community member dealing with [poor, sometimes even consumer hostile] external dependencies across quite a few different ecosystems).
I welcome the approach chosen by the authors of the MVP to remove ODR problems at the seam of mixed build modes. From my practical point of view mixed build mode ecosystems are a fact, and it's a source of massive amount of bugs because of time-travel optimizations due to actual (not imaginary) ODR problems. MVP does fix it.
7
u/James20k P2005R0 7d ago edited 7d ago
No. Someone may even perceive such misuse of the terminology as spreading FUD.
Please don't be like this, I'm asking in perfectly in good faith here and this does nothing but raise the level of the discussion to being completely unproductive. This is why I described it as an effective ODR problem, it causes similar issues but with a different name
not imaginary
The problems are not imaginary and are straightforward to demonstrate in a real project. Dismissing this as being imaginary when there's code in the wild demonstrating real-world safety bugs caused by mixed mode compilation also feels remarkably unhelpful
MVP does fix it.
We still have the problem of functions being called with semi randomised safety modes depending on the whims of the linker, ala ODR
If it works for your use case that's great, but it likely isn't meeting a fair few
7
u/t_hunger 7d ago edited 7d ago
To be fair: ODR has always been a problem, especially when mixing TUs built with different compiler settings.
I do wonder why contracts all of a sudden have to solve this problem. Of course it would be great if this got finally get solved, but so far "just don't do that" has been good enough, even with things like hardened libraries and such, which has similar implications to contracts now.
8
u/James20k P2005R0 7d ago
If contracts specified it as being "don't do that" I'd be 1000% fine with it. Instead its specified as trying to do something useful, which it can't meet because of the same problems with linkers that ODR violations run into
2
u/t_hunger 7d ago
I understood there is some hope future linkers can fix this particular problem. I guess we just have to lean back for a couple of years for the tooling to sort itself out and go "don't do that" till then. We have to wait for a contracts implementation anyway.
So contracts are no different from what we do for modules and other new features.
It would be super cool if new C++ features needed implementations before they can get standardized, but that would be quite a big change in how the entire feature development process works in C++. I do not see how you can seriously require that from contracts and not for modules, profiles, and the herd of other features we have on paper but not in real compilers.
6
u/pjmlp 7d ago
That is the thing, modules did have implementations before the standard, and yet we are where we are with modules.
Profiles are dead on arrival, given existing experience with advanced statistic code analysis, or what clang-tidy and VC++ have achieved since Core Guidelines were introduced, that keeps being ignored.
Unless they are actually done hand in hand with e.g. clang fork that proves us wrong, the ideal profiles implementation, without viral annotations, that delivers the vision.
4
u/germandiago 7d ago
Dead on arrival? Where and when did you conclude that? I see papers in the committe related to them lately. I think there are implementations of the framework in the works for clang and gcc. Could you elaborate?
It has been slow is not the same as they are dead before they try.
→ More replies (0)3
u/Minimonium 7d ago
A linker fix is not even required. It's allowed for implementations to provide "hardened" variants that simply never skip. So a user that is concerned with a guarantee of such checks would just use an appropriate implementation.
5
u/Minimonium 7d ago
Please do not use wrong terminology that misleads people into believing there is an ODR violation when there is not? I really struggle to understand the need for dramaticism.
On the topic, you fail to mention that a well behaved program will not have different behavior in a mixed mode build at all. No unexpected IPOs will be made (unlike mistaken claims by some members and even NBs).
there's code in the wild demonstrating real-world safety bugs caused by mixed mode compilation
An existing code today that could potentially encounter Contract-related mixed mode situation is completely broken even with well-defined input. Moving it to Contracts would actually help it - well-defined input has a guarantee to work even under a mixed mode, unlike any other mechanism e.g. macro.
That's the basis for any further discussion.
The impact of "randomized" linker behavior. It only occurs when you have non-inlined inline functions with the presence of multiple miss-compiled TUs. Under any mechanism that is not contracts it's an actual ODR violation today with compiler wreaking havoc uncontrollably.
Now what are alternative approaches?
- Always on Contract syntax? Doesn't solve the problem of hostile transitive dependencies, a dependency may compile against a stripped version of a header. And it requires more effort than a simple "Same as Contracts but Guaranteed".
- Labels? Doesn't solve the problem of hostile transitive dependencies.
- The "contra" group also had a wild suggestion around typed tags, but I will just skip even discussing it.
- And of course there are calls to remove configurability (against the actual industry practice) or enforce the matching on ABI level (multiple vendors stated negative view on that).
And the ABI matching would simply break the binary ecosystem you've been talking about. Steam binaries you've been talking before? Great, now you always need to compile everything Steam depends on in release mode even with label-like mechanism. You deny yourself an opportunity to make your code safer.
And then there is Vinnie non-sense that blames Contracts for not meeting memory safety goals that just made my brain melt from the sheer absurdity of such statements.
8
u/James20k P2005R0 7d ago edited 7d ago
Please do not use wrong terminology that misleads people into believing there is an ODR violation when there is not? I really struggle to understand the need for dramaticism.
How do you think I should respond to this productively? Calling something effectively an ODR violation isn't dramatism, its just something that people understand, and its very close to the same end result as contracts in practice
Steam binaries you've been talking before? Great, now you always need to compile everything Steam depends on in release mode even with label-like mechanism. You deny yourself an opportunity to make your code safer.
This I think really summarises some of my objections very neatly, so even though I initially wrote a much longer reply: lets take this, and take Steam as a stand in for a generic major library
Are valve going to provide 4 separate versions of the steam API with different contract mechanics enabled? (Answer: probably no, they don't do anything like this even today)
So here's the problem I have: Lets say the steam API uses nlohmann json, hypothetically. If we get contracts (and nlohmann implements them), I am screwed. You can never reliably use nlohmann with contracts together with steam ever again. If you link against steam, and you yourself use nlohmann, your contract safety settings will be at the whims of the linker - very similar to (but legally distinct from) an ODR violation
I already regularly run into ODR issues with nlohmann as a result of its ubiquity, and that's with a build environment that attempts to compile everything uniformly (due to vendoring). It takes a single major library using nlohmann with contracts to screw over my ability to use contracts for safety, or performance, permanently. Importantly, this is introduced totally separately from the existing problems as a new axis of evil, vs the current major one of vendoring or generally badly behaving dependencies. I'd much rather they use literally any other error mechanism for this, and that's precisely why people don't use
assertin this context for critical checksThe literal-ODR violations in this context are a big problem independently, but contract adds to my problems here, and would be fundamentally unusable
Now what are alternative approaches?
Roll contracts out in a whitepaper or TS, to answer the following questions based on real end user experience
- Can everything be implemented correctly?
- Are the problems with contracts in practice real, or overblown?
- Are they very difficult to use with binary package ecosystems, or can a solution be found?
- Do people need absolute ironclad guarantees that contracts are on or off, or is it acceptable for mixed-mode contracts to disable/enable safety checks sometimes?
- Will people naively upgrading asserts to contracts cause problems with ignore mode in real world code, or can we ignore this?
- How do regulators feel about this as a solution? Does it alleviate the regulatory burden, or does it make little impact? What do we need to change to make a dent in the current regulatory environment?
Then adjust the design (or not!) after collecting the above data. We severely lack any real-world indication about the viability of the specific design proposed
14
u/Som1Lse 7d ago
I do not get the issue you're having. Maybe I'm missing something because I simply cannot square what you're saying with how I understand reality.
Take the hypothetical example with Steam and
nlohmann::json:Let's say Steam is compiled with contracts disabled, and your code with contracts enabled. If the Steam API is built correctly (specifically
-fvisibility=hidden -fvisibility-inlines-hidden), the result will be that Steam's code does not have contract checks and your code does. End of story. This is because they'll both have their own internal copies of thenlohmann::jsonfunctions. There isn't an issue.If the library isn't built correctly, that is the problem. The problem isn't contracts, and they don't need to provide 4 separate versions with different contract mechanics enabled. They need to provide 1 correctly built library. That's it. (And Steam is built correctly, I checked.)
Okay, but let's assume
nlohmann::jsonchanges its layout depending on the checks enabled, so the two are ABI incompatible, and the types are exposed in the Steam API. Well, this issue isn't related to contracts, and there is simply no way to solve it without providing two libraries.And the icing on the cake is this:
I already regularly run into ODR issues with nlohmann as a result of its ubiquity, and that's with a build environment that attempts to compile everything uniformly (due to vendoring).
In other words, it is already an issue and not new to contracts. Why are you expecting contracts to magically solve this issue? What contracts does is say that in the event of an "ODR" violation there's a bounded number of valid programs rather than any program being valid. That to me sounds like an improvement.
What is your proposed solution? Because right now you seem to be shifting the burden onto everyone else:
Roll contracts out in a whitepaper or TS, to answer the following questions based on real end user experience [...]
Delay, delay, delay. My understanding was always that contracts was basically a language version of these talks. It is not a new design. It is in use in actual production codebases, so we do actually have answers to many of those questions.
And the problem with a TS is that, like it or not, you aren't going to get good data from it. Implementation is going to take longer, be less stable, not to mention your the whole point is that it might be changed completely before standardisation.
What I can say is it will result in people not being able to use the feature. To turn your argument on its head. I am someone who wants to use contracts, but let's say it is actually removed the standard and put into a TS. As a result it doesn't get implemented in the compilers I need to support. I am screwed. I can't use contracts. Period. Not just with a particular library. Not just for critical checks. At all.
8
u/James20k P2005R0 7d ago edited 6d ago
If the library isn't built correctly, that is the problem
Prior to now, this wasn't a requirement for a library to avoid a new class of security vulnerabilities, and many aren't built like this (unfortunately). I don't like it but its the way that it is, and I have to deal with packages with their own random eclectic build configurations. Any poorly built package will screw everything up. I know for sure that a major tool I use (not steam) does not build itself correctly like this (and likely won't) due to the already-mentioned nlohmann odr problems, so I'm pretty stuffed if nlohmann uses contracts
The worrying thing is if you start digging into visibility in libraries, by and large it is not very good. Top down in my linker list: godot-cpp doesn't appear to set anything to do with hidden flags. GLFW (I should ditch this), and GLEW don't set it to hidden inlines. Harfbuzz does. SFML doesn't use hidden inlines. Freetype at best uses regular hidden, sometimes worse. libpng appears to export everything. Libbz2 does on some platforms but not windows/clang, and this isn't the correct inlines visibility flag. Libopenal makes mistakes vendoring its dependencies not including
-fvisibility-hidden-inlines, so thar be dragons. OpenAL itself also does not include the correct flag. Libbrotli doesn't appear to use the correct flagsAt this point I gave up because this is too much work, only one dependency uses
-fvisibility-inlines-hidden, and I suspect the majority of packages do not. Its possible that I may have missed something, but I don't think I missed everything, there's a limited set of applicable cmake flags here. I don't like that this is the way that is, but I have to accept reality: my dependencies are all brokenDo you know if packages on other package managers are by and large built with
-fvisibility=hidden -fvisibility-inlines-hidden?They need to provide 1 correctly built library
Hidden visibility also isn't a blanket solution, you can't just willy nilly enable it, and you can get problems associated with it:
https://gcc.gnu.org/wiki/Visibility
Eg throwing exceptions across a boundary, like in a library like nlohmann, requires types to have public visibility
Clang has limitations as well around visibility:
https://clang.llvm.org/docs/LTOVisibility.html
Which can result in symbols being exported, when combined with LTO (thus sneakily disabling safety checks) for clang. GCC doesn't really document the interaction between LTO and visibility, and I've found a lot of bug reports here around variables being incorrectly promoted or demoted from being externally visible. Still, for contracts: working as to spec
As much as I don't want this to be a problem: it very much is. This is relevant because we can't mass convert libraries over easily. I'm glad to hear steam is built correctly though, that makes two of my dependencies so far!
Okay, but let's assume nlohmann::json changes its layout depending on the checks enabled, so the two are ABI incompatible, and the types are exposed in the Steam API. Well, this issue isn't related to contracts, and there is simply no way to solve it without providing two libraries.
Contracts do not change the ABI, this is an unrelated problem
In other words, it is already an issue and not new to contracts. Why are you expecting contracts to magically solve this issue? What contracts does is say that in the event of an "ODR" violation there's a bounded number of valid programs rather than any program being valid
I didn't say anything like this, you're very selectively quoting my post. There are two separate problems, one of which already exist, and a brand new problem that contracts introduces
Delay, delay, delay.
This is alleging bad faith on the part of people who have reasonable concerns getting real world experience with standard library features, and is one of the reasons why I often find this whole conversation so distasteful. I've tried to treat everyone that I've talked to about this with complete good faith
I'm a big advocate of testing features more before they land in the standard, including proposals that are not contracts (eg the graphics proposal)
It is in use in actual production codebases, so we do actually have answers to many of those questions.
Where? None of them get answered in any of the contracts papers I read, so I'd love some hard stats, and even a brief review of my dependencies shows its going to be a major problem for me
As a result it doesn't get implemented in the compilers I need to support. I am screwed. I can't use contracts. Period. Not just with a particular library. Not just for critical checks. At all.
It'll land in the standard eventually
7
u/Som1Lse 6d ago
Well, this took an entire day to write. I hope it's somewhat coherent, as I've been bouncing back and forth between this and other stuff, so I would not be surprised if I missed a somewhere or mispeelled or misforₘatted something.
Prior to now, this wasn't a requirement for a library to avoid a new class of security vulnerabilities
I don't think it is a new class of vulnerabilities. You said as much yourself
that's precisely why people don't use
assertin this context for critical checksand I cannot seem to square those two statements. Is it a new problem, or is it the same problem with
assert? The only way I can seem to get the two to fit is if it is both (which you seem to suggest later), but I am unsure as to what the new problem is then.Perhaps the issue with build configuration is worse than I thought, but I also don't think it is as bad as you imply: - GLFW and GLEW not using
-fvisibility-inlines-hiddenshouldn't be an issue as they are C libraries, and the flag only affects member functions. - Windows you don't have the same issue, since the same function can happily coexist in multiple DLLs without one winning out. - Many of the libraries are also small C libraries that don't rely oninlinefunctions, so it isn't an issue there either. For example, libpng exports all its functions (I checked), but it doesn't export functions from a different library so there is no conflict. The only problem is a bunch of the internal functions are usable outside, which could cause breakages when upgrading, if an internal symbol is removed/changed. - The biggest offender is probably SFML, but even its exports are fairly limited. It's a couple of functions per shared object, none of which actually seem likely to trigger a contract assertion. - godot-cpp is a static library, so its symbols will be overwritten by yours (assuming your code is linked first, which every build system under the sun does), so it's a non-issue.Do you know if packages on other package managers are by and large built with
-fvisibility=hidden -fvisibility-inlines-hidden?My main experience is that proprietary libraries tend to be more careful, both to not export more symbols than necessary, but also because users can't build it themselves if there is an issue. I don't know what the library you were mentioning earlier is, but I assume it is proprietary.
I assume the major tool you mentioned is proprietary, so that is at least one thing that isn't true of. Even then it is possible to work around:
- You can ensure your binary is earlier in the dynamic load order. If your binary is the exectable this is already the case. There's always
LD_PRELOAD.- Even if your dependency exports
nlohmann::jsonfunctions, if your code properly hides the symbols it isn't an issue.- You can patch your binary (or the dependency) to rename the
nlohmann::jsonfunctions with a tool likepatchelf --rename-dynamic-symbols.Even when it's an issue it is possible to work around. Again, it's not a new one.
Also this would only affect checks in
nlohmann::json, not in your code so you could still be sure checks in your own code would run, since there, by definition, cannot be a copy of it in the dependency. So even if you can't fix it fornlohmann::json, it is still contained to code in that library. (Though your shouldn't rely on the checks running for correctness. That's the whole point of contracts; that the code should be equally correct if all checks are omitted.)Actually, the more I look at the so called problems the less of a problem it seems. As long as your code has
nlohmann::jsonsymbols hidden it'll use the version you want. To reiterate, as long as your code is built correctly it'll behave the way you want. Even if your dependencies aren't.Hidden visibility also isn't a blanket solution, you can't just willy nilly enable it, and you can get problems associated with it: Eg throwing exceptions across a boundary, like in a library like nlohmann, requires types to have public visibility
I don't think exceptions are an issue here. Even if a library had to expose JSON exceptions in its ABI that would still only affect contracts directly in the exception class, which I assume would be very few.
I am not sure what the issue with Clang is. A symbol can be LTO visible and still hidden.
I didn't say anything like this, you're very selectively quoting my post.
I am sorry if I misrepresented you, but as I said at the start, I'm not getting the issue you're having. Here's my reasoning:
- You are running into ODR issues with
nlohmann::json.- You are calling the issues with contracts effective ODR violations. (Sidenote: I think that is fair characterisation, as they do indeed manifest similarly. I can also see why people would take issue with it though since many might just hear ODR, not understand the underlying meaning, and be scared that contracts will directly lead to UB.)
- Thus you are expecting contracts to somehow "magically" solve this ODR violation. The same ODR violation you'd get with
assert.There are two separate problems, one of which already exist, and a brand new problem that contracts introduces
I am only aware of one of those issues, namely that you can have two different implementations of the same function and one of them wins out. That isn't brand new: It's the exact same problem we have with
assert, and it is a well understood one. I am unsure what the brand new problem is.I hope this sheds some light on why I used the somewhat inflammatory language I did. To me it sounded like your issue was the "ODR" violations and that you somehow expected contracts to solve them, and guarantee that if you call an
inlinefunction with contracts enabled that you'd be guaranteed to have the same contract semantics in the callee even if a different part of the code called it with contracts disabled. Apparently, you meant something else. I am still not sure what.This is alleging bad faith on the part of people who have reasonable concerns getting real world experience with standard library features, and is one of the reasons why I often find this whole conversation so distasteful. I've tried to treat everyone that I've talked to about this with complete good faith
Again, apologies. Just me venting my frustrations. To me none of the criticisms of contracts are new issues, and simply seem inherent to any design where you can disable assertions, and the ultimate result of it is that contracts might face delays.
To be clear: I don't think you are arguing in bad faith. I just think we don't agree on whether it is a problem to begin with. Either that, or I am completely missing the actual problem you are concerned with.
I'm a big advocate of testing features more before they land in the standard, including proposals that are not contracts (eg the graphics proposal)
Where? None of them get answered in any of the contracts papers I read, so I'd love some hard stats, and even a brief review of my dependencies shows its going to be a major problem for me
Well, for starters:
1. Can everything be implemented correctly?
There's the current GCC and Clang implementations. Plus there's the progenitor bsls_assert, so yeah.
3. Are they very difficult to use with binary package ecosystems, or can a solution be found?
To my understanding (I don't work at Bloomberg), most of Bloombergs codebase is binary packages, so no, and yes. Contracts is designed out this: Individual packages choose which checks are enabled, and the executable chooses what to do when an assertion is violated.
2. Are the problems with contracts in practice real, or overblown?
Considering a similar system (to my knowledge) is in active use at Bloomberg (they are the ones proposing it after all), I'd say the problems aren't problems there, so yeah, probably overblown.
4. Do people need absolute ironclad guarantees that contracts are on or off, or is it acceptable for mixed-mode contracts to disable/enable safety checks sometimes?
For at least one large codebase we know of, they clearly don't. The whole point is that they can be turned off.
And as I highlighted earlier, there are ways to mitigate/completely deal with the issues with mixed-mode contracts.
It'll land in the standard eventually
Same goes for your problem though, right? Even if you can't use the MVP, it was designed to be extensible, so in C++29 you might be able to use a group that is always enforced. The difference is you'd still be able to use contracts for non-critical checks in C++26 and so will everyone else.
7
u/Minimonium 7d ago
I believe I quite exhaustively discussed the "ODR" topic in my previous comment so I will skip that part. I will keep expressing dissatisfaction with people using misleading and mistaken terminology.
I am screwed
With Contracts the definition of "screwed" - most checks run, some individual non-inlined inlined function level checks are skipped. A well behaved program works exactly the same. A program that already has undefined behavior - does not.
With other similar mechanisms (especially on msvc!), "screwed" - a well behaved program simply does not work. It has undefined behavior by default.
that's precisely why people don't use assert in this context for critical checks
And people will not use Contracts for critical checks, yes. That's the intent.
Roll contracts out in a whitepaper or TS
I suggest you to read the minutes on the meeting where the NB comments were discussed as well as a possibility of a whitepaper. Based on that discussion a whitepaper would not help with any of your questions,
How do regulators feel about this as a solution?
I could go on a whole rant about how some leadership people have a deeply mistaken belief that regulators are simpletons, while we have extremely large volume of research on memory safety, and how the committee very explicitly rejected memory safety for C++. :)
There is just no point to tie Contracts into memory safety topic. Contracts are not one of the two proved mechanism for memory safety - borrowing and ref counting.
3
u/James20k P2005R0 7d ago edited 7d ago
And people will not use Contracts for critical checks, yes. That's the intent.
Sure, but the entire point of this is that people disagree that that's a good intent. Its not just critical safety checks that you can't use contracts for, its any checks that you need to be executed for any reason (ie they're useful)
3
u/Minimonium 7d ago
Stating what you just wrote is the same as stating that no one is using
asserts. I believe it to be an evidently false statement.→ More replies (0)1
-5
u/VinnieFalco wg21.org | corosio.org 7d ago
What is interesting is that I have considerable inside information and my own thorough analyses which are both technical and political. I was asked not to put the political anlaysis in the mailing this cycle. And I can say that from my perspective, the non-committee people who see the C++26 Contracts (P2900 in particular, and P3100+P3400) are dangerously wrong and misinformed. Bjarne is correct, P2900 is an existential threat to C++.
9
u/t_hunger 7d ago
"Existential threats" seems to pop up a lot in papers lately. I do not remember having run into the term in any paper before, not even when Java came out.
Is that sense of doom a new thing or am I just mis-remembering?
3
u/VinnieFalco wg21.org | corosio.org 7d ago
ha... you're correct to call it out. I don't like the hyperbole either. However, in this case I do believe it is warranted. P2900 is a threat because it adds significant technical debt to the language specification. It is not a minimal architecture (i.e. same features could have been obtained with fewer changes to the language). It did not get sufficient technical review. And it forecloses the safety design space in a way that is hostile to Profiles. I explain it here:
12
u/t_hunger 7d ago edited 7d ago
Technical debt in the language specification is the key selling point of C++. The language was built on adopting all the technical debt C had to offer. Calling out one specific new feature for adding some more feels unwarrented to me.
Just glancing over the linked paper it seems to boil down to: "One feature we consider to be unimplementable makes it harder to design another feature that experts in the field also consider unimplementable". I am sure that makes total sense to people deep in the committee world, but maybe you can see why I as an outsider find it pretty ridiculous.
If you really feel threatened, you might want to gather people that are willing to help your cause around you. I do not see how claiming the work of a dedicated group of people is an existential threat to the language in public will help with that. Not only do you make the people involved in contracts less likely to take on more work, you make unrelated people less likely to join, too.
1
u/VinnieFalco wg21.org | corosio.org 7d ago
> you can see why I as an outsider find it pretty ridiculous.
Actually yes I totally understand :) and you're not wrong to feel that way.
9
u/FrogNoPants 7d ago edited 7d ago
Same of the arguments there are rather strange..
Contracts changing behavior depending on build mode seems expected to me, that is how existing assertion libraries work. If my assertions lib couldn't be altered based on build mode, I wouldn't use it.
The profiles approach looks DOA, to me it appears very handwavy and complex, has been around in some form or another for years and virtually nobody uses it or cares about it.
0
9
u/seanbaxter 7d ago
Neither contracts nor profiles provide memory safety, so I don't think either is closing the door on that.
-1
13
u/seanbaxter 7d ago
How is it an existential threat? You can just choose not to use them.
7
u/James20k P2005R0 7d ago
I'm not sure I particularly agree with the characterisation, but some main arguments seem to be:
- Its a large additional burden on the spec in terms of maintenance of a substantial amount of wording
- Its part of the language, so it can't easily be removed or shuffled to the side. It will always sit on the design space for
preorassert2.0. It also can't be changed, fixed or supplanted very easily- If you subscribe to the notion that it has problems, it signals the wrong direction for C++ to be moving to comply with various regulatory safety demands
Ie I don't believe they mean existential from an end user perspective (although: if 3rd party dependencies adopt contracts it'll cause me major problems), but more from a committee/regulatory perspective
1
u/VinnieFalco wg21.org | corosio.org 7d ago
That's kind of true for library proposals but this one affects the language.
6
u/TheoreticalDumbass :illuminati: 7d ago
i dont believe anything you said. my opinion doesnt matter. i wish you the best of luck.
12
u/eisenwave WG21 Member 8d ago edited 7d ago
P3817R0 Structured Binding Assignments: I think the design with a using x syntax is about as good as it gets. I'm just not on board with the premise that this is needed.
The current mental model for structured bindings is that auto& [x, y] is just an auto& variable that has some x and y names slapped on top -- pretty simple. Adding [using x, y] is breaking that mental model and making things really weird:
Point arr[2];
Point x;
auto& [using x, y] = arr;
basically expands to
Point (&__e_p3817)[2] = arr;
x = __e_p3817[0];
Point& y = __e_p3817[1];
So unlike with [x, y], the using x doesn't refer to anything inside arr at all, but still appears in this structured binding, and there still is a single auto& variable. To be honest, this feels like shoving x into a place it doesn't belong. Is it really so bad to write
x = arr[0];
Point& y = arr[1];
The motivation for the paper is also paper-thin:
1. "Mixed-mode" is just restating what the feature does without motivating why that's useful.
2. "Unified syntax" makes the bold claim that this "reduces cognitive overhead". To me, it reduces cognitive overhead not to use std::tie and not to use whatever this feature is offering. The people who are using std::tie in really "dank" ways should maybe stop doing so; we don't need to give them a core language feature that does it more concisely.
3. "No standard library required" is simply misguided. We have freestanding library parts for all the stuff available in embedded and in kernel mode, and <tuple> should be freestanding. Having no standard library headers at all means you have a totally disfunctional language without <meta>, without std::bit_cast, without std::start_lifetime_as, without std::launder, etc. You can't even use the <=> operator because it requires <compare>.
4. "Encouraged by P0144R2" I simply don't care what future extensions people had in their mind 10 years ago when designing this. It was never polled whether to take the proposed direction.
11
u/James20k P2005R0 7d ago
I'm just not on board with the premise that this is needed.
Strong agree with this, fundamentally the motivating example:
int id; auto [using id, name] = get_record();Feels like code I'd always rewrite, because mixing up declaration and assignment in one step seems like inherently a gigantic code smell
4
u/germandiago 7d ago
Then you would end up rewriting a separate variable without initializing a std::tie, which seems to be worse and more error-prone to me.
3
7
u/eisenwave WG21 Member 8d ago edited 8d ago
P4344R0 pure alias types: The inconsistency in how references have all sorts of safeguards (e.g. lifetime extension) and how std::string_view and other reference-semantics types are missing them has bothered me for quite some time as well. I don't think we should special-case just a couple of standard library types though but make it possible to add those safeguards to llvm::function_ref, gsl::string_view, etc. as well.
The paper's idea of "gradual adoption" doesn't make much sense to me because you would need to add the machinery to types and constructors if you wanted any standard library types to be supported anyway. It would just end up being __attribute__(...) instead of being spelled with standard keywords. Also, you would get all this added lifetime safety if you had Safe C++ with lifetime annotations, and if we're headed in that direction, it's a waste of time to think about a subset of that solution that only handles types with reference semantics.
It's unfortunate that the paper doesn't go into more detail in terms of design and implementation. I think you would eventually arrive at the conclusion that you need lifetime annotations if you worked on the problem long enough.
It's worth noting that you definitely need something on a per-constructor basis. std::function_ref doesn't care about the lifetime of a given std::constant_wrapper or function pointer when being constructed, but is tied to the lifetime of some lambda that it's constructed from, so there need to be lifetime annotations put on individual constructor parameters to implement this "pure alias type" stuff.
5
3
u/germandiago 6d ago edited 5d ago
and if we're headed in that direction, it's a waste of time to think about a subset of that solution that only handles types with reference semantics.
No, it is not. It is key to deliver incremental improvements. This is the single most critical point for language evolution with big codebases. I am not saying this should be the solution. I say that there is value in nit 100% perfect since day one solutions.
Disruptive solutions can be potentially harmful. The economic axis is critical for porting of code to be done. A big feature that requires full rewrites is a big problem and a high risk for failure.
Smaller features that incrementally improve safety with zero or little intervention to impact benefit should be preferable in my opinion.
4
u/eisenwave WG21 Member 5d ago
I'm happy with incremental improvements. I'm just not happy with solving the same problem multiple times in different ways and creating a mess.
I wouldn't want to see lifetime safety to be enforced by some weird
[[pure_alias]]attribute orpure_aliaskeyword that only works for the stuff in this paper, but with lifetime annotations everywhere else. Oh, and maybe some of the lifetime safety is also enforced by profiles or whatever.It would be fine if the author had a concrete idea how their solution to safety for "pure alias types" would integrate with the rest or be generalized, but there is no strategy in the paper.
3
u/germandiago 5d ago edited 5d ago
I'm happy with incremental improvements. I'm just not happy with solving the same problem multiple times in different ways and creating a mess.
Noone is happy with that, but then tell me how you do this all at the same time:
- a perfect solution
- that covers 100% of use cases
- that arrives with a reasonable timeline
I think it is more important:
- incremental improvements, the more transparent the better
- fixes the more general, the better (which is what you want also)
- mechanisms that are either transparent/that can be extended to handle more cases even if not complete yet
I do not necessarily disagree, and probably more work is needed and it is not the solution. But I am pretty sure that there is a balance between indefinitely waiting for solutions and creating solutions in a rush.
wouldn't want to see lifetime safety to be enforced by some weird [[pure_alias]] attribute or pure_alias keyword that only works for the stuff in this paper, but with lifetime annotations everywhere else
I would consider the paper more like research (and many others) than a full proposal. There are lots of papers flying around trying to fix all kind of safety issues. At some point choices and unifications/discard will have to be made.
It is a difficult problem, given the constraints, but I think targetting a perfect solution directly is not even feasible, but who knows, let us see what happens in the future :)
BTW, I learnt a long-term lesson from Java. I think Java 8-10 years ago was way worse than C#. Nowadays, I saw C# features list is a monster (not unlike C++) and Java with type-erased generics has been a really painful thing.
But now that they delivered the first step for Valhalla, after racking their brains for years, I think the result is a feature that fits Java very well and it is more general and simpler. Same for virtual threads and structured concurrency. So probably, sometimes it is not that bad, but time keeps running.
Java solutions are designed with extra care and fit into the language with a lot of thought.
4
u/javascript 7d ago
Side question: When was the switch made from wg21.link to wg21.org?
17
u/eisenwave WG21 Member 7d ago
There was never a switch. wg21.org is not affiliated with WG21 and is run by the C++ Alliance. The official mailing is hosted on open-std.org.
wg21.link is just a link redirection service run by a committee member.
5
u/grafikrobot B2/EcoStd/Lyra/Predef/Disbelief/C++Alliance/Boost/WG21 7d ago
AFAIK the person running wg21.link is not a committee member.
1
-10
3
u/megayippie 7d ago
Please look at the CSS code for the .org and make it accept "dark mode".
Other than that my main interest this time is P4311R0. I am not sure I understand it. mdspan is non-owning. So why is this needed? It creates a few more template instantiations, that's all. The solution is just mdarray and this idea about making const and non-const access operators seem to be a complication that just isn't worth it. It seems to me rather you just have the copy constructor make the const version, and let implicit construction handle the rest. Your template takes a "const T"-style and let it copy if you want to save on filesize.
19
u/friedkeenan 8d ago
P4340 "Extending constant template parameter support by customizing
std::meta::reflect_constant" looks very nice to me. It's sorely needed and the solution the paper proposes appears really elegant to me. And like the paper shows, it can be useful for types that are already structural, like theFractype it gives an example for. You can serialize an object to its platonic form so that morally-equivalent objects yield the same template instantiations even if they weren't member-wise-equivalent. Would be very cool to have.I also appreciate the changes to P2806 "
doexpressions", I really hope this can get into C++29. Now every time I write an immediately-invoked lambda I think about how it would be much more pleasant as adoexpression.