The irony.
I don't understand what's the difference.
I'm not an expert in writing real-time safe code, but I've spent close to a year working on allocation-free programming. Implicit copies of structs (value types) are as fast as implicit copies of integers, but implicit copies of types with owned heap memory invoke the copy constructor, which calls into the allocator. Or did I misunderstand your comment or get anything wrong?
With a handful of exceptions you essentially will never need to worry about this if you restrict assignment and argument passing of non-POD types to references within the critical code blocks. And in the case that you do need to worry about it, the copy constructor should be explicitly deleted anyway.
It's a footgun to be sure, but it's not a serious one with a bit of discipline. If you're used to doing real-time safe programming, you'll get paranoid about code that could invoke an allocator (or write your own).
It's a working strategy, but if you forget the `&` in `auto & x = document.foo; auto & y = x.field;` a single time, it might silently invoke the allocator. What actually happened to me was that it crashed because I returned a reference to a stack variable copied by mistake, when I meant to type a `&`. Pointers are probably less prone to accidental copying, but they have uglier dereference syntax and are nullable (excluding custom types).
Ever since that incident, I've been paranoid that I accidentally forgot the reference in another spot in the code. A few days ago, I debugged the code and set a breakpoint on malloc in the audio thread (LLDB crashes when listing threads, Visual Studio works) and found out my current codebase doesn't allocate on the audio thread. I hope I don't introduce any allocations.
To avoid this footgun, objects could be only copyable through an explicit `clone()` method like in Rust (which breaks std::vector<explicit_clone>), or by marking copy constructors as explicit (which you can't do to a std::vector).
Really though, you shouldn't have an owned STL instance like std::vector near your real time code to begin with. You're seeing one of the reasons people writing performant code don't use the STL at all, even if it has gotten up to par with handrolled solutions in certain benchmarks.
As well as having nicer syntax in general and real metaprogramming instead of the brain damage that is templates, zig promotes this kind of allocator-aware programming style in a way that's clean and idiomatic
In C++, you have to pass around an allocator to your templates. You can typedef this away if you want.
In Zig, you have to pass around an allocator as a function argument or a struct member. You can comptime this away if you want.
Is there some fundamental way that I missed that Zig changes this? If your actual complaint is that C++ templates are bad and you're saying Zig comptime is better, that's different than having woes about allocators.
(hint: there is no way to do this)
You don't need to do this if you're using allocators.
The other thing is that Zig doesn't seem to have any real plans to support C++-style closures right now. If they ever find a type-safe way to do it while supporting custom allocators, then that would be interesting, but at the moment I wouldn't say it's any better than C++ in this regard.
I actually have seen some C/C++ libraries that do allow changing the default allocator although it's usually only low-level libraries that bother to do this.
In general, I have not observed a consensus for 'idiomatic' C++, even within a single project. I say this as someone who wishes there was, because my job would be a lot easier if dependencies were less heterogeneous :)