Also It would be really dumb to use shared_ptr for every case of allocation
"I have a complete tree of object ownership with a single allocated root" is also a mess for a different reason - you literally never delete anything. Either you have a very very strange application or you are being massively wasteful with memory pressure.
It would be really dumb to use shared_ptr for every allocation. But it is the only way in C++ to systematically ensure that you never have a uaf (I guess you could also have a custom allocator and a custom pointer type that does a null check on every dereference - but now you are paying a major performance cost for a lock and a branch on every dereference). That's why I mention the benefit of a GC. You can get safe lifetime access without shared_ptr everywhere (or going all the way to where Rust went and demanding very explicit lifetime annotations for the compiler to use).
Shortest answer - I do not get scared into using particular tools just because they're "safe" and in practice I've never had to deal with the problems you mentioned in my products. There are also various tools that catch these kinds of errors for C++ and other languages. I do use those them tools ;)
You might belong to the rarified class of uber-developers who can write bug-free C++ applications, but if that class of people exists it is a small one.
This is an interesting take coming from a person who writes the tools. Obviously you know way more about it. I do understand that if I for example link ASAN and it does not show errors for a while it is not a guarantee. The software just might not hit that error path. But I am a practical man running my own company and can not be a perfectionist. If software passes my own test, analyzers and other tools do not report anything suspicious and I have no bug reports from a customer I can sleep well and count my money ;)
>"You might belong to the rarified class of uber-developers who can write bug-free C++ applications"
I absolutely do not write bug free applications but I tend to have very few to begin with and I do eradicate them pretty fast. Some of my stable releases run for years without any bug related complaints. Not sure if that qualifies for "uber". I am however very good architect and deliver solutions in very diverse areas. Desktop, multimedia, enterprise backends, middleware, device control firmware etc. Also understand electronics.
I think that asan is also theoretically unsound (I don't know its innards well enough) based on how it actually tags pages but in practice this isn't super relevant. The question is whether you actually execute the problematic sequence in some build that has asan enabled.
> Not sure if that qualifies for "uber".
Writing C++ code with minimal memory errors would qualify as "uber", given the data available from both academic and industrial research on C++ application development. The data is very clear - real applications run into these issues with frequency even when they consistently use modern smart pointers.
Since the server exposes proprietary JSON API with what I would say extreme validation before trying to actually do anything nothing that seems to be illegal gets in.
I mean it is not 100% guarantee as nothing else in our lives but so far nothing extraordinary (keeping my fingers crossed).
That's true. But if you do the preferred thing of using unique_ptr then you still happily access memory beyond the lifetime of an object via some bug.
> Uaf bugs are much rarer.
This is not true. You can go look at CVEs for large projects like Chrome that have teams of people trying to weed out these kinds of issues and still see UAFs where absolutely nothing is allocated with "new."
You cannot access memory you have no pointer to, not even accidentally.
With a GC, there is a global owner so you don't have to think about ownership for everything, this breaks down for some resource release (maybe half of objects) which is not necessarily easier. But typically GC languages also allow you to use RAII, though maybe not as consistently as C++.
What kind of programs can have unclear ownership? Basically everything that doesn't need to be high quality.
- Memory managing of concurrent containers. Lock-free algorithms requires GC or the hazard pointers and these are basically based on GC.
- You often need the GC engine when you implementing or integrating another language.