On Sunday, 24 July 2016 at 09:03:04 UTC, Lodovico Giaretta wrote:
On Sunday, 24 July 2016 at 02:17:27 UTC, Rufus Smith wrote:
[...]
Now you are telling me to "program by trust", because there's
nothing ensuring that I remember to free everything I allocated
with malloc/free, while a GC would guarantee no memory leaks.
Again there's nothing stopping me from returning pointers to
things allocated on the stack. And now there are lots...
Before you told me that programming by trust is a wrong
attitude, and now you propose me to use it, risking memory
leakage in a function that may be executed hundreds of times
per second.
[...]
No. If you put a big @nogc attribute on Object.opXXX, then
nobody can write GC code in his classes. So if everything is
@nogc, you cannont write GC code, because it woudn't interact
with Phobos. Example: if you mark an algorithm that takes a
delegate @nogc, then you cannot pass GC delegates to it. So you
cannot use it in GC code.
[...]
Yes. All building blocks must be as much @nogc as possible. But
customization points (virtual functions, delegate arguments,
...) must not be @nogc, otherwise it is no possible to have
classes that use the GC or callbacks that use the GC.
[...]
I still don't understand why you want Object.opXXX @nogc. As I
already said, you can still make your functions @nogc, just
accepting parameters of @nogc types. It's obvious. If I wrote a
wonderful library that uses the GC, you will not use it. If I
have a class that uses the GC in opXXX (and I am free to have
it, because maybe I need it, and maybe it's the most efficient
way for my use case), you will not use it. The same applies
here. You'll have your algorithms work only on classes that
declare opXXX as @nogc.
Not all memory allocation patterns are good for malloc/free.
Not all of them are good for stack allocations. Some of them
are not even good for reference counting. Every class shall use
the best solution for its job. And everybody must still be able
to extend the base class.
If you want to use a method specific to a subclass, you
downcast. If you want to use the @nogc opXXX when the base does
not enforce it, you downcast. It's the same principle: more
advanced functionalities require more derived types (and @nogc
is more derived, because it is covariant to not-@nogc). Basic
OOP.
I believe Rufus was only referring to the virtual methods defined
in the object class. That would be:
toHash (Note: this is already nothrow, that's intersting and
quite restrictive)
opCmp
opEquals
I think all 3 of these are good candidates for @nogc. However,
AFAIK, making them @nogc would break any code that implements
them because they would have to add the @nogc attribute to their
implementations (unless I am mistaken? Do subclass overrides
need to explicitly have @nogc if the parent class does?). If
adding @nogc is not required in the implementation, then the only
code that would break would be implementations that actually do
allocate GC memory.
Some would think that restricting GC usage inside these virtual
methods is a good thing because it has the benefit of
discouraging memory allocation for these types of operations.
Really, you probably shouldn't be allocating memory to perform a
comparison. If you really need to, you can either allocate non
GC memory, or use a different mechanism then the opCmp/opEquals
methods.