For those who are not familiar with C++, the past ~12 years have seen _massive_ changes to the language, the standard library and the surrounding ecosystem. Yes, old programs still run, but they are simply not what you would write today nor how you would write today.
In fact, the C++20 changes are so significant that it will take years for developers to even transition to utilizing them, like it took years for C++11 to be more-or-less widely adopted.
Of course they're adding things to C++. They've been adding things to C++ for decades. I don't anticipate that slowing down for many years if ever. Watch Herb Sutter talking about the question of whether C++ is "finished" a few months back. Bjarne wants Unified Functional Call Syntax, which is the sort of crazy "automatic foot-shotgun" feature that C++ deserves and will fit right in†. Herb wants a pattern matching syntax which of course also de-structures, has overloadable typecasting and includes dynamic type ID as well because this is C++. There's no shortage of additions to C++
But C++ is too complicated and too unsafe. The only way to actually fix that would be to face the monster and slim down C++ and that would threaten backwards compatibility and thus can't be countenanced any more. In that same talk Herb talks about these big problems, claiming he's going to address them. But what he actually does is a sleight of hand trick. He redefines the problem. C++ isn't too complicated it lacks extra features that would make it more orthogonal. So adding yet more stuff to it will fix that. C++ isn't too unsafe it's just too easy to get things wrong, adding yet more stuff will avoid that.
Nobody should be convinced by this hogwash.
† UFCS says foo(a, b) and a.foo(b) are the same thing. In Rust you get one half of this coin, you can call any function at all as a free function, if you can write a.foo(b) there's a (verbose and usually not idiomatic) way to write foo(a,b) instead with the same effect. But you can't do the reverse because it would break a lot of Rust assumptions. In C++ today in most places you need to know whether to write foo(a, b) or a.foo(b) because only one of them will work.
The point is not the _adding_, it's the effective _replacement_. It's like a toolkit with some lame tools. Even though you keep them in there for old time's sake, you add new tools which you use instead of the old ones. So, yes, your toolkit is heavier, but working with the updated toolkit is not like it was working with the old one.
> C++ is too complicated
Well, it is certainly complicated. Certainly more complicated than anyone would like, including the WG21 bigshots. But its (effective) design principles necessitate complexity:
1. Multi-paradigmaticity (sp?)
2. Backwards compatibility
it could drop one or both of those and be much simpler, like you suggest.
> The only way to actually fix that would be to face the monster and slim down C++
Except then it wouldn't be C++, but another language - which is fine. Another famous quote by Stroustrup is: "Within C++, there is a much smaller and cleaner language struggling to get out"
... but that language would not be Rust, it would be slimmer underpinnings of is idiomatic C++20 today. Or perhaps of what idiomatic C++26 would be :-P
> C++ isn't too unsafe it's just too easy to get things wrong
I disagree; or rather, these days, I disagree: This has, paradoxically, gotten much much better - because of all of those additions you decry. They have made it so that you can steer clear of unsafe and complex territory for a lot more things. You write more intuitive, safer code; and are better protected by the libraries you use and by improved tooling. It's true that the underpinnings of these libraries are now (usually) bigger and more complex, but the end result for the developer is the opposite.
---
PS - I would really love UFCS to get into the language, I think the opposition to it is kind of inane.
UFCS fits perfectly with C++ culturally. In particular UFCS means when Library A provides a function that says it can twiddle a foozle, Library B that provides foozles and explicitly doesn't want you twiddling them can't stop anybody calling foozle.twiddle() and C++ says as a programmer the resulting mess lands in your lap.
> Except then it wouldn't be C++, but another language - which is fine.
Hogwash. It's C++ if they say it's C++.
When I first wrote some C++ I could write:
auto foo = something();
That was a very strange way to say "int foo" because auto meant automatic (ie local) storage and the default type was int. But it was legal C++ when I was a teenager.
But, today if I write:
auto foo = something();
That's a variable whose type will be chosen automatically (C++ auto is not merely inference and will choose something even when it isn't clear what you meant).
That was not another language, it was still C++ it was merely changed in an important way. In C++ 20 and particularly in the decision to not take Epochs, they decided C++ must never again be changed.
> They have made it so that you can steer clear of unsafe and complex territory for a lot more things.
No. Putting a little wooden fence along the crumbling edges of a fast mountain road and saying "Now it's safer" is almost worse than not bothering. It is concerning that this fools people.
Real safety looks quite different, consider my misfortunate::Maxwell type in Rust. The Rust traits this implements are definitively safe. If you try to store a bunch of Maxwells in a Hashset things won't go well for you since Maxwells aren't Equal (even to themselves) and yet they all Hash the same. But whereas in C++ such things get you Undefined Behaviour and all bets are off, in Rust we have safety and so the behaviour may be useless (e.g. infinite loop) but it is never Undefined. Our program is wrong but because it's safe we can successfully reason about why it doesn't work.
> Without the ability to break ABI, the C++ standard library is dead.
I agree that the ABI should be broken. However, the standard library is not dead, for 2 reasons:
1. There could be switch to an std2 namespace for new versions of things, or of the whole library. And then std3 etc.
2. There _will_ be a switch to standard library via _modules_, and with that switch the ABI is changing anyway, so it could be used to make changes to existing ABI
... that being said, a lot of the standard library, while not dead, is kind of brain-dead, like std::map and std::unordered_map; or how you need the mountain of code that is ranges to be able to say `vec2 = transform(vec1, my_func)`, even though that was perfectly doable with C++11 at the latest, etc.
> Why have an ABI then ?
Because that way compiled code can work with other compiled code without them being compiled together? :-(
Yeah, I have an issue with the term ABI - application binary interface. It is misleading because if it were really a binary interface, you could interoperate with code compiled in other languages. But you cannot do this in C++.
C++ doesn't have an ABI. It just pretends to have one.
For those who are not familiar with C++, the past ~12 years have seen _massive_ changes to the language, the standard library and the surrounding ecosystem. Yes, old programs still run, but they are simply not what you would write today nor how you would write today.
In fact, the C++20 changes are so significant that it will take years for developers to even transition to utilizing them, like it took years for C++11 to be more-or-less widely adopted.