It seemed to me that you were picking only the bits you like from that SO thread, in order to support your argument:
You mean like you just did when you only quoted the single line on unique_ptr? And chose to delete the parts specifically discussing the overhead of other types of smart pointers?
implying "smart pointers have extra overhead", which is wrong. Without further relativation this statement is misleading.
It is not wrong. Quit saying that. Again, you are the one who is "picking only the bits you like" from the SO article.
The article lists the overhead associated with various different smart pointers.
That list does not say "smart pointers have no overhead".That list does say "these types of smart pointers have this kind of overhead, which in some cases is zero.
It is fine for you to point out unique_ptr has no overhead.
It is not fine for you to keep conveniently omitting the costs associated with shared_ptr.
It is not fine for you to keep calling me wrong, when the article clearly and plainly states there is overhead with certain aspects of smart pointers.
If you want to discuss the responsible and limited use of shared_ptr, due to the overhead it incurs, cool. That is an informative conversation, based on the facts.
Unfortunately I'm going to need to ignore the next couple pieces of your post that continually reiterates the argument that smart pointers have no overhead. Again, arguing for the restricted use of unique_ptr only is a different thing. We can do that. But it is different.
Yes, and typically, you can design your code in a way so that one of these pointers owns the memory and the others are just referrers. If you know in advance who frees the memory, you don't need shared ownership.
Ok, now we're reaching somewhere useful.
What do you do in this scenario?
Do you use a unique_ptr as the "memory owner" pointer, and a raw pointer in the "non-memory owning" copies?
If so, I actually think that is a reasonable solution. But I think a lot of RAII advocates would have a problem with this.
But I'd also like to point out that manual memory management is completely sufficient in my case. For my manager class which owns the memory, a simple delete call in the destructor completely handles the problem.
Fallacy #1: "I am using new/delete because I need more control over my code."
According to this logic, you'd program in C, if not Assembly.
If someone wrote a program in C, it worked, and it didn't leak memory, I would be 100% ok with this. If they further claimed C provided all the tools they needed to achieve it, I would be 100% ok with this.
You keep speaking in absolutes. I think this is where we will ultimately reach a stand still in our debate. I believe in very few absolutes when it comes to coding. I take into consideration the strengths of the coder, the requirements of the task, and the characteristics of any existing code base. I am wiling to accept different tailored solutions (e.g. RAII vs. no RAII) depending on these factors.
regarding link-time:
I see, but I would really be surprised if this a) could not be deactivated (VAX has a step filter feature, so it's a matter of tools), and b) this would have a measurable impact,
I appreciate your suggestions. But with large programs in visual studio, there's only so much you can do. It's not just in my own code bases I've encountered slow link times, but also at every job I've ever worked at working on large software.
and c) this impact would outperform the time you lose if you make only one mistake related to manual memory management. You're paying a very high price for this.
You have no idea how much time, or how many mistakes I make using manual memory management. You can assume, if you like. Perhaps based on your own bad experiences. But you should not project these issues onto me.
Fallacy #5: "Unique pointers are overkill in this situation"
Fallacy #XI: "A single programming technique must be applied to all problems"
Fallacy #3: "Memory management is only unsafe when you use it incorrectly/in an unsafe way"
Fallacy #VII: Manual memory management cannot be done safely. It can, and has across many years in millions of programs.
Just look at Font.cpp, it's a big mess with tons of different resources that all need to be deallocated in different ways, and failure to load one must account for all the others. A C++11 handle class with move semantics would simplify this code dramatically, while making it more robust at the same time.
I had a look at Font.cpp. Based on a very quick brows of the code:
There are 3 variables that use new/delete: m_refCount, m_stream, and a m_streamRec.
There are 5 calls to new.
There are 6 calls to delete.
That hardly strikes me as an unmanageable "big mess".
Some of these are due to a hand-rolled pointer-based reference count. I probably would have advocated for a different solution. I would not have objected to smart_ptr in this situation.
There appears to be other dynamic memory allocation via calls to FT_Get_Glyph and FT_Done_Glyph. Based on my quick examination, this does not appear to be something smart pointers would help with, as you are restricted to the syntax provided by FreeType.
If you consider this an unmanageable problem without smart pointers, I would suggest we have different abilities to deal with manual memory management.
You have not been developing it. Because in the API, SFML doesn't use raw pointers that own memory. At least I don't recall an interface that expects you to allocate something with new, or gives you something that you must deallocate with delete.
Yes, SFML is written with good memory management.
I have found the code a pleasure to work with.
Fallacy #4: "Many people use smart pointers incorrectly"
Fallacy#XXIII: Smart pointers are always used correctly.
Fallacy#XXIV: Smart pointers will guarantee your programs (and libraries you employ) do not leak memory.
There may be a few situations where you need a more flexible/loose form of RAII, like shared ownership. And there are higher-level "leaks" like cyclic references or std::vector::reserve() that are out of RAII's scope.
Exactly.
So we are in agreement memory leaks may occur regardless of the use of RAII.
That was the primary point of my original post.
Programmer errors are not a good argument because bugs in the memory leak detector can occur as well, and even more so with manual memory management. And as many threads in this forum (maybe this one too?) show, it's possible to use leak detectors incorrectly, or interpret their results in a wrong way. So it only guarantees something as long as you use it correctly, and we're back to the circular logic.
Yes, memory leak detectors can be used incorrectly.
Yes, RAII can be used incorrectly.
Anything you use incorrectly can cause problems.
I provided a ton of rational arguments for RAII, I even skimmed through many places in the Internet to collect different views on the topic and write a detailed article about it. It's not a matter of taste or "art" (fallacy #6), but hard facts. And I did not call you foolish.
Pardon, you say ignorant, not foolish.
As noted above, I believe we are at an impasse. We believe fundamentally different things about the art of coding.
I did want to respond though, to clarify my opinion. And to refute your repeated assertions that I was incorrect. If you want to keep posting that, there is nothing more I can do than what I have written above.
I also responded to to demonstrate how unhelpful it is to post these absolute "fallacy" rules, when I can just as easily post opposing fallacies. Discussing in terms of these false absolutes does nothing to further the conversation.
However, I am genuinely interested in your technique in dealing with "multiply pointed to" memory in RAII, without the use of shared pointers. Should you decide to elaborate. I appreciate that aspect of the discussion.