"Hey, that C++ code that's been working for years? All wrong! Go rewrite it in Node.js. No, no, no, in Go this time. Now Rust!" ...
"Hey, that C++ code that's been working for years? All wrong! Go rewrite it in Node.js. No, no, no, in Go this time. Now Rust!" ...
No, I didn't work on Rust for the past six years while sitting in the office twirling my mustache trying to think of ways to slow the industry down.
I worked on it because we kept seeing the same issues come up again and again and again.
That being said, I've been knowing game developers for years and while I don't know their exact complaints, they kept saying they wished they were working with something else than C++.
I think it's mostly solving the same problems many times over and over, during their entire career.
So, yes technically you CAN write nice lightweight C++; but you won't be able to enforce it in a team, as everyone will need 'their' pet feature of doom to bring back the bloat.
How do I know? Well, I tried for years to do it like that; and eventually I had to give up. Now I do plain C, because it can't be corrupted in the same way.
"But, but, I just #included <vector>!!"
"... What, for a 5 byte constant array?"
"Yeah I know, but the compiler will just inline it!"
#include <boost/fusion/container/vector.hpp>
"Why do we need Boost for this single vector?""Well... We're using Boost elsewhere..."
Now we use C. Not C++.
On the other hand, in C you are stuck with a built in array now. If you pass this to a function that doesn't get inlined, it will decay into a pointer, then inside that function the compiler has actually "lost" knowledge of the size of the array. Now you have to pay for a loop.
In C++ you can pass a std::array by const reference, the compiler knows exactly how big that array is at all times, and for small arrays the loop checks can be eliminated entirely.
Many of the arguments against C++ boil down to: if you're working with a lot of people who have a knowledge level below what I would expect someone with 1 year of good experience to have, then they can make more mistakes. Is the level of developers generally really that low?
To which my answer would be "write your own". Whenever I program in C I always use my own dynamic, bound checked arrays that store their own length.
I am often surprised that many C programmers often don't build their own abstractions. The OpenSSL library is a prime example of this - the same 4 or 5 arguments passed in the same order to hundreds of functions. I am always surprised they didn't just make a struct.
It can store it's own length, but the compiler will still not be aware of the length, except in a real local context (i.e. in the same block of code, either actually, or via inlining). So if you decide to loop over your array, you have to pay the price of looping (jumping and comparing).
If you know that you are working with an array of fixed length, and you use a C++ std::array, you can pass this by reference to functions and those functions will know at compile time how long the array is. So you don't have to pay for looping at all; if you do something small in a loop the compiler will unroll it to 3 assignments or what not.
In addition, the reason that C programmers don't build their own abstractions is because C does not have templates. So building your own abstraction either means that it's not very abstract (i.e. restricted to one data type), or you are using void, or macros, or both. These things are all horrible to work with, void based data structures also involve a performance hit. This tilts the trade-off between writing abstraction and single-use code far, far towards the latter.
In C++ you have templates which are far better for writing your own data structure than macros, and have no performance penalty.
It's not strictly a subset of C++, but rather focuses on syntax and semantics that are convenient for the rapid development/exploratory refactoring and high performance that are characteristic of game dev.
Lots of tools for different kinds of manual memory management, build rules integrated into the source, syntax support for easily switching between "arrays of structs" and "structs of arrays" (and data-oriented types in general), simple static typing with type inference, that kind of thing.
[0] https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md