4 ms·
Interesting how C++ is still improving; seems like changes of this kind my rival at least some of the Rust use cases; time will tell
by BinaryIgor 10mo ago
Interesting how C++ is still improving; seems like changes of this kind my rival at least some of the Rust use cases; time will tell
- semiinfinitely 10mo ago> Interesting how C++ is still improving its not
- Conscat 10mo agoDo you read the Clang git commit log every day? C++ improves in many ways faster than any other language ecosystem.
- deleted 10mo ago[deleted]
- Maxatar 10mo agoI think he was referring to the language specification, not a specific compiler.
- actionfromafar 10mo agoBut that is also wrong, as per the article C++ 26 got some improvements in a hardening profile.
- Maxatar 10mo agoI see that C++26 has some incredibly obscure changes in the behavior of certain program constructs, but this does not mean that these changes are improvements. Just reviewing the actual hardening of the standard library, it looks like in C++26 an implementation may be considered hardened in which case if certain preconditions don't hold then a contract violation triggers an assertion which in turn triggers a contract violation handler which may or may not result in a predictable outcome depending on one of 4 possible "evaluation semantics". Oh and get this... if two different translation units have different evaluation semantics, a situation known as "mixed-mode" then you're shit out of luck with respect to any safety guarantees as per this document [1] which says that mixed-mode applications shall choose arbitrarily among the set of evaluation semantics, and as it turns out the standard library treats one of the evaluation semantics (observe) as undefined behavior. So unless you can get all third party dependencies to all use the same evaluation semantic, then you have no way to ensure that your application is actually hardened. So is C++26 adding changes? Yes it's adding changes. Are these changes actual improvements? It's way to early to tell but I do know one thing... it's not at all uncommon that C++ introduces new features that substitute one set of problems for a new set of problems. There's literally a 300 page book that goes over 20 distinct forms to initialize an object [2], many of these forms exist to plug in problems introduced by previous forms of initialization! For all we know the same thing might be happening here, where the classical "naive" undefined behavior is being alleviated but in the process C++ is introducing an entire new class of incredibly difficult to diagnose issues. And lest you think I'm just spreading FUD, consider this quote from a paper titled "C++26 Contracts are not a good fit for standard library hardening" [3] submitted to the C++ committee regarding this upcoming change arguing that it risks giving nothing more than the illusion of safety: >This can result in violations of hardened preconditions being undefined behaviour, rather than guaranteed to be diagnosed, which defeats the purpose of using a hardened implementation. [1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2900r13.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p29... [2] https://www.amazon.ca/dp/B0BW38DDBK?language=en_US&linkCode=gg2&linkId=76565ec8504083fbaae116133da82c20&tag=bfilipek-20 https://www.amazon.ca/dp/B0BW38DDBK?language=en_US&linkCode=... [3] https://isocpp.org/files/papers/P3878R0.html https://isocpp.org/files/papers/P3878R0.html
- aw1621107 10mo agoI believe there were some changes in the November C++ committee meeting that (ostensibly) alleviates the some of the contracts/hardening issues. In particular: - P3878 [0] was adopted, so the standard now forbids "observe" semantics for hardened precondition violations. To be fair, the paper doesn't explicitly say how this change interacts with mixed mode contract semantics, and I'm not familiar enough with what's going on to fill in the gaps myself. - It appears there is interest in adopting one of the changes proposed in D3911 [1], which introduces a way to mark contracts non-ignorable (example syntax is `pre!()` for non-ignorable vs. the current `pre()` for ignorable). A more concrete proposal will be discussed in the winter meeting, so this particular bit isn't set in stone yet. [0]: https://isocpp.org/files/papers/P3878R1.html https://isocpp.org/files/papers/P3878R1.html [1]: https://isocpp.org/files/papers/D3911R0.html https://isocpp.org/files/papers/D3911R0.html
- blub 10mo agoThe implementations of hardening in libc++ and libstdc++ are available now and are straightforward to use. https://libcxx.llvm.org/Hardening.html https://libcxx.llvm.org/Hardening.html https://gcc.gnu.org/wiki/LibstdcxxDebugMode https://gcc.gnu.org/wiki/LibstdcxxDebugMode (was already available for longer, the official hardening might take this over or do something else)
- menaerus 10mo agoMixed mode is about the same function compiled with different evaluation semantics in different TUs, and it is legit. The only case they are wondering about is how deal with inlined functions and they suggest ABI extensions to support it during the link-time. None of what you said is an issue. > The possibility to have a have a well-formed program in which the same function was compiled with different evaluation semantics in different translation units (colloquially called “mixed mode”) raises the question of which evaluation semantic will apply when that function is inline but is not actually inlined by the compiler and is then invoked. The answer is simply that we will get one of the evaluation semantics with which we compiled. > For use cases where users require strong guarantees about the evaluation semantics that will apply to inline functions, compiler vendors can add the appropriate information about the evaluation semantic as an ABI extension so that link-time scripts can select a preferred inline definition of the function based on the configuration of those definitions.
- galangalalgol 10mo agoThe issue with safer c++ and modern c++ is the mirror of the problem with migrating a code base from c++ to rust. There is just so much unmodern and unsafe c++ out there. Mixing modern c++ into older codebases leaves uncertain assumptions everywhere and sometimes awkward interop with the old c++. If there was a c++23{} that let the compiler know that only modern c++ and libc++ existed inside it would make a huge difference by making those boundaries clear and you can document the assumptions at that boundary. Then move it over time. The optimizer would have an advantage in that code too. But they don't want to do that. The least they could do is settle on a standard c++abi to make interop with newer languages easier, but they don't want to do that either. They have us trapped with sunk cost on some gaint projects. Or they think they do. The big players are still migrating to rust slowly, but steadily.
- kaz-inc 10mo agoThere kind of is. There's __cplusplus, which I'll grant you is quite janky. #IF __cplusplus==202302L
- GeorgeTirebiter 10mo agoI'm wondering if the C++ -> Rust converters out there are part of the Solution: After converting C++ to Rust, then convert Rust to C++ and you now have clean code which can continue to use all the familiar tooling.
- aw1621107 10mo ago> I'm wondering if the C++ -> Rust converters out there are part of the Solution Are there C++-to-Rust converters? There are definitely C-to-Rust converters, but I haven't heard of anyone attempting to tackle C++. > After converting C++ to Rust, then convert Rust to C++ and you now have clean code which can continue to use all the familiar tooling. This only works if a hypothetical C++ to Rust converter converts arbitrary C++ to safe Rust. C++ to unsafe Rust already seems like a huge amount of work, if it's even possible in the first place; further converting to safe Rust while preserving the semantics of the original C++ program seems even more of a pie in the sky.
- josephg 10mo agoI’m not really sure how checks like this can rival rust. Rust does an awful lot of checks at compile time - sometimes even to the point of forcing the developer to restructure their code or add special annotations just to help the compiler prove safety. You can’t trivially reproduce those all those guardrails at runtime. Certainly not without a large performance hit. Even debug mode stdc++ - with all checks enabled - still doesn’t protect against many bugs the rust compiler can find and prevent. I’m all for C++ making these changes. For a lot of people, adding a bit of safety to the language they’re going to use anyway is a big win. But in general guarding against threading bugs, or use after free, or a lot of more obscure memory issues requires either expensive GC like runtime checks (Fil-C has 0.5x-4x performance overhead and a large memory overhead). Or compile time checks. And C++ will never get rust’s extensive compile time checks.
- blub 10mo agoThey rival Rust in the same way that golang and zig do: they handle more and more memory-safety bugs to the point that the delta to Rust’s additional memory-safety benefits doesn’t justify the cost of using Rust any more.
- simonask 10mo agoZig does not approach, and does not claim to approach, Rust's level of safety. These are completely different ballparks, and Zig would have to pivot monumentally for that to happen. Zig's selling point is about being a lean-and-mean C competitor, not a Rust replacement. Golang is a different thing altogether (garbage collected), but they still somehow managed to have safety issues.
- pjmlp 10mo agoIt could have gotten them, had the Safe C++ proposal not been shot down by the profiles folks, those profiles that are still vapourware as C++26 gets finalised. Google just did a talk at LLVM US 2025, regarding the state of clang lifetime analyser, the TL;DW is we're still quite far from the profiles dream.
- 10mo ago
- fpoling 10mo agoRust borrow checker rules out a lot of patterns that typical C++ code uses. So if C++ would get similar rules, they still cannot be applied to most of the existing code in any case.