DIP60: @nogc attribute
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Mon Apr 21 05:00:50 PDT 2014
On Fri, 18 Apr 2014 20:17:59 -0400, Walter Bright
<newshound2 at digitalmars.com> wrote:
> On 4/18/2014 5:30 AM, Steven Schveighoffer wrote:
>> Absolutely not, the compiler knows whether the count needs to be
>> incremented, I
>> don't need to know.
>
> But there are manual escapes from it, meaning you need to know to use
> them:
>
> unsigned char *vdata = data.data;
> // process vdata
>
> I am skeptical that the O-C compiler is sufficiently smart to make ARC
> on all pointers practical. That snippet pretty much proves it.
I finally understand what you are saying.
Yes, when my code devolves into C-land, I have non-ARC pointers. This
means I cannot store these pointers somewhere if I don't keep a pointer to
the object that owns them. This is indeed manual memory management.
But, and this is a big but, I DON'T have to care about memory management
as long as I only store pointers to objects, aside from the stack. Objects
themselves can store non-ARC pointers and manage them privately, but not
allow arbitrary setting/getting of pointers. This is not very common.
A great example of where I use arbitrary non-GC pointers, is an object
that stores a network packet.
unix sockets work just fine in networking and iOS, so I do all of my
networking with socket, send, recv, etc.
These functions take unmanaged char * pointers.
So an object that stores a single packet does this:
1. read the packet header into a structure overlay. Figure out the length
(this is a TCP packet).
2. malloc a char array with the proper length, read in the packet.
3. verify the packet is correct, if not, free the buffer.
4. If it's correct, digest the packet (storing fields from the packet data
itself, byteswap, etc.). Then store the data into an NSData object, giving
it ownership of the buffer.
All this happens within a factory method. I never directly store the char
* array inside the object or elsewhere, it gets wrapped into an NSData
object, which will then free the data once the object is destroyed.
You must be conscious about memory management, because after all,
Objective-C *is* C, and you are allowed to do stupid things just like in
C. But you CAN have a certain set of rules, and as long as you follow
those rules, you will not have to deal with memory management.
> Total replacement of GC with ARC in D will:
This is the wrong straw-man, I'm not advocating for this at all.
> 1. Be a massive change that will break most every D program
> 2. Require people to use unsafe escapes to recover lost performance
> 3. Require multiple pointer types
This isn't what I had in mind anyway. I envisioned an ARC system like
Objective-C, where the type pointed at defines whether it's ARC or GC.
For instance, GC would be *required* for array appending in D, because
arrays cannot be ARC-managed. You would need a wrapper type for ARC, with
it's own semantics.
> 4. Will not be memory safe (see (2))
> 5. Require the invention of optimization technology that doesn't exist
Besides being a tautology, what does this mean?
> 6. Become more or less ABI incompatible with C without a long list of
> caveats and translations
Again, this is based on your straw-man which I don't advocate for. The
change I had in mind was much less invasive.
> A much more tractable idea is to implement something like C++'s
> shared_ptr<> as a library type, with usage strategies paralleling C++'s
> (and yes, use of shared_ptr<> would be unsafe).
shared_ptr would work (and I've used that extensively too, it's awesome
for C++), but I feel it's a much less effective solution than a
compiler-augmented system that can optimize away needless
increment/decrements.
Note that shared_ptr would never be able to handle D's slice appending
either.
-Steve
More information about the Digitalmars-d
mailing list