I don't use smart pointers since shared ownership is a bad concept.
The problem of memory management is largely trivial.
Google et al have been working on sanitisers etc because, even in well kept codebases with strict coding standards that are rigorously applied in reviews, memory bugs do actually creep in.
This applies regardless of programming language.
Of course the web people and their "frameworks" is just another demonstration of how bad relying on third party code is.
def f(x)
return ...
in Python or Java, those functions will work regardless of what other modules I import. (modulo monkey patching in Python, though you can defend against that)In C you don't have these guarantees -- foreign code can stomp on your code.
This is probably why C does not have an NPM-like culture of importing thousands of transitive dependencies -- because that style would just fall down.
Also a minor issue, but C doesn't have namespaces (for vars or macros), so it's a bit harder to compose foreign code.
Also compiler flags don't necessarily compose. Different pieces of C code make different portability assumptions, and different tradeoffs for speed.
That is just plain false, since a Python module can trivially be tainted by what you import before, and the Python environment is widely known for its dependency hell.
Meanwhile C modules, once compiled, can be fully isolated from what you link against them, depending on build and link settings.
Non-local bugs is just a matter of sharing state across a module boundary. Memory errors is just a very small subset of the possible bugs you can have in a program, and preventing them doesn't magically solve all the other more important bugs.
This is actually an important point. I think all codebases can (and should) be split into small, opinionated, privately owned sub-codebases. This is why developing large scale projects can work even in languages like C. After all this is what that whole 'modularity' thing is about ;)
(it also implies that external dependencies need to be managed the same way you handle internal dependencies, as soon as you use an external dependency you also need to be ready to take ownership of that dependency)
Arguably that's even a good idea in memory safe languages, it avoids tricky borrow checker issues, and also prevents the outside world to directly manipulate objects. Everything happens under control of the system.
Or you could give the message in fragments to the user, but that immediately becomes a very inconvenient API.
I think you mean you don't use shared smart pointers? Or do you avoid unique_ptr too?
Of course I know unique_ptr.
If you witness the endless amount of bugs, many security related, which stems from the idea that people can handle memory, I'd say it is far from a trivial problem.
If you witness any modern language, a common design principle is to eliminate memory management. Which argues it is far from a trivial problem.
There is a reason C++ still reigns supreme even though it was built in the 90s.
More manual memory management methods still have their place, because there are problems where you can't afford to use a garbage collector, or where it gets into the way.
C++ will be relevant for many years to come. It has way too much momentum as a language and too much software has been written in C++ to ignore it. I personally think Rust will eventually carve up a large part of its niche though, because I think it has a far better approach to managing memory.