He states D isn't different enough to encourage most devs to go through the pain of switching. If they are going to switch, they would like that language to be much better targeted at solving game dev specific needs.
He states D isn't different enough to encourage most devs to go through the pain of switching. If they are going to switch, they would like that language to be much better targeted at solving game dev specific needs.
I also think that, due to it's early start, D simply fails to appeal to non-C++-developers. The other new native compiled languages, Go and Rust, are not just a new toy for C++ people, but are also seen as long awaited "on metal" opportunities for people from other language backgrounds (python and ruby for go, type-heavy managed languages for rust), who would never touch c++ or, guilty by association, D. This is a much bigger audience than the subset of c++ devs willing to give up their hard-earned mastery of c++. The perceived promise of native for high-level devs might not hold, but this won't help D at all.
Edit: yeay the downvote bandwagon, you should go to a AAA studio and ask about C++.
Relatively small backend apps written in C++ may be a better target for D and Rust.
The difference is that they only do it when the OS vendors, or game console vendors, force them to adopt new languages in their SDKs.
I know many gamdevs using Unity, LUA, Javascript, Gamemaker and a ton of other options.
There are reasons why AAA studios stick to C++: they don't know any better, they're in constant crunch-mode and don't have time to look for better alternatives, they use an existing engine with years of development history and don't want to invest in a new one, they target platforms where only C/C++ compilers are available, etc.
You'd be surprised of the horrors you can find in a game's C++ code base (there are gems too, but you kind of expect those.)
While it's true that some languages make some horrors easier to bring into the world (if you take away people's access to the memory, for example, you remove an entire class of memory-related nightmares), in my experience, the key requirement for creating these horrors isn't the language; it's the programmer and the constraints they're working under (such things as inexperience, painful levels of urgency, inappropriate processes, team churn, and so on and so on). People can and will make horrors in any language, and if D becomes the new C++, in twenty years people will be saying the same things about D.
When I think about all the different variable initialization rules in C++ I know I'll get it wrong in crunch time and most likely get it wrong when all my work conditions are perfect because there's like 7 different rules. And that's for one feature only.
D doesn't make it impossible to write horrors, it just doesn't ask for it the way C++ does.
First there was only Assembly, C and Pascal dialects were dog slow, and the OS vendors forced them to go C.
Then there was only C, C++ was dog slow, and the OS vendors forced them to go C++.
Then there was only C++, language X was dog slow, and the OS vendors force them to go language X.
The question is what language X stands for.
https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced...
And the new generation usually comes with a fresh set of ideas about things, and some of the newbloods will be "stupid" enough to start and rewrite some of the C++ tools, at the expense of their employers that will see delayed projects and tons of bugs because of this, and probably fire the trouble-makers, but the retooling will happen anyway, so it's probably better for people to embrace it and start allocating budget slices for it.
take for example a lot of C++ samples that that guy shows in the video, he calls it "C++11" and uses code like:
- void* data = NULL;
- no STL
- no stack allocations
- only dynamic memory allocation using new and delete
i mean come on..
Stack allocations are discouraged because they can introduce non-deterministic bugs (stack overflow depending on the call sequence which can't be predicted in advance).
Its nearly impossible to write a game without dynamic allocations. Most of the time they'll override the new/delete operators and on that level they work almost exclusively on void*.
You're working on a scale where a lot of the C++ features work against you.
that’s probably because most of the AAA games you've seen used old in-house libraries that replaced the STL, since the earlier STL implementations weren't the best.
STL is not 100% the way to go every time, but i would say that nowadays unless there’s a really specific implementation need, it should be used at least 90% of the times, even if only for base for new data structures to be built on top of.
- "Stack allocations are discouraged because they can introduce non-deterministic bugs (stack overflow depending on the call sequence which can't be predicted in advance)."
i really don’t understand this problem, you can change the stack size on every compiler and every OS either on compile time or runtime. also, are you writing functions or methods with 10k LoC?
stack allocations are actually easier to follow than heap, its not even close..
- "Its nearly impossible to write a game without dynamic allocations. Most of the time they'll override the new/delete operators"
yes i agree, dynamic allocations are still really needed, and not only for games.
But, overriding new / delete operators in C++ when you can set custom allocators and deallocators for both unique_ptr and shared_ptr? once again i think that’s more of a legacy code update problem than an actually implementation need problem.
- "and on that level they work almost exclusively on void*."
only if they want to, that’s what templates (and again the STL) are here for.
I’m not saying pure C++11/14 features are the only way to go, i just think that at least in new code it should take priority, the cleanness and robustness it provides its just too good to ignore.
Last time I looked std::vector::clear() wasn't required to release memory and caused a lot of headache when certain implementations wouldn't free the underlying memory.
I'm aware that the work around is to assign a new std::vector<T>() but that always felt like more of a hack then anything else.
On the last AAA game I worked on we had very tight memory constraints and running about a dozen threads. Almost all of them used the minimum stack size except for the main thread. There were still a lot of stack allocations, but only for very small temporary objects and when the call stack was known to be shallow. Using megabytes for stack sizes would consume a noticeable percentage of the available memory which was direly needed elsewhere.
I've seen one game using shared_ptr and it was far from being great. There's a big overhead to it when compared to custom allocators. You can't easily optimize for cache locality with shared_ptr (as far as I know!) and working around enable_shared_from_this can be a real pain. With custom allocators you can easily optimize according to the use-cases.
Finally, templates are required to know their type at compile time, which for things like allocators is just not possible in many cases. For example, we used a bump-the-pointer allocator for a frame's temporary values which could be of any type but still needed cache locality. We also used a fixed-size allocator when avoiding memory fragmentation was more important than cache locality. Both would be impossible to do on anything but void*.
I haven't taken the time to dig into seeing how these techniques will translate to Rust(obviously unsafe).
I've lost count of the number of times I've thought to myself "I wish C++ has this D feature." A lot of them are being added now but the interesting ones (concepts!) are still years away and some (inout functions!) are nowhere in sight.
And then there's templates, mixins, auto this, compile-time reflection, and so much more. Its far from perfect (nothing is) but constantly improving and rather productive. Of course also being a user of Clojure (and Emacs-LISP) I sometimes miss something like defmacro, which I can almost get with mixins and templates but often not as elegantly. On the other hand, I write shell scripts in D all the time and not in Clojure!
they didn’t really "fix" it, instead they added a method called std::vector<T>::shrink_to_fit() which i'll admit its not the most elegant way, but it works.
what it does is, it resizes the capacity() to be the same as the size(), deallocating all the extra memory.
"Abstractions like RAII, constructors and destructors, polymorphism, and exceptions were invented with the intention of solving problems that game programmers don’t have, and with the result of interfering with the solutions to problems that game programmers do have."
...that's basically enough to make me never bother to look him up again. We don't need more special purpose languages, we need more general purpose ones. That's the cool thing about D and Rust and Go too. You can easily use the same language for anything from simple scripts (D even has rdmd that basically works like a ruby/python-style interpreter to run a file without even compiling!) to, I don't know, navigation control code for a drone.
We really don't need more special purpose tools now, the hardware allows us to have languages that span the full spectrum from metal to web page (via compile-to-js, but still...), so let's use this. Yeah, full-spectrum languages will be neither C-like (like close enough to metal so you can see the resulting machine code in your head) nor Javascript-like (idiot-friendly but professional-hostile), so we should prepare for some "weirdness".
It's not like we don't already know that this is possible since like 30 years ago: Lisp machines used one high level language for everything from OS to GUIs but and it worked great, with the exception that their price/performance ratio was horrible, but now we kind of solved the problem of building dirt-cheap machines, so we can get back to dreaming awesome stuff! And in the games world, I think that John Carmack has partially "seen the light" too, and maybe he'll convince more people of what he's seen ;)