February 27, 2015
On 2/27/15 7:17 AM, Manu via Digitalmars-d wrote:
> There's no mention of const/immutable...? Surely we can have RC
> immutable things right? I can't see how that works here... but it's
> very important.

Yah. I've added a TODO.

> I'm not clear on structs. What is the order for calls; postblit,
> opInc, opDec, destructor? 75% of my use cases today are thin structs
> that wrap C/C++ api's.

Structs don't get any special treatment with DIP74, only classes and interfaces.

> There's no mention of 'scope'. I presume functions that receive scope
> RC arguments will have the opportunity to have opAddRef/opRelesae
> elided around the call?

That might be a future improvement. In fact that may be possible today; I've spoken to an ARC expert who read DIP74 and said Apple's ARC does not insert a retain() for a function call, i.e. it assumes functions only borrow unless they actually do keep a pointer (e.g. assign to a member or global), and only in that case inserts a retain().

If I'm not missing something, we can do this with DIP74 which will reduce the opAddRef/opRelease traffic quite a bit.

> I wonder if some standard GetRefCount function should exist? Otherwise
> they will probably end up being named all sorts of different things. I
> guess I can't think of any value in a standardisation of the function
> otherwise though...

Yah, leave that to users.


Andrei


February 27, 2015
On Thu, Feb 26, 2015 at 11:35:55PM -0800, Walter Bright via Digitalmars-d wrote:
> On 2/26/2015 5:37 PM, H. S. Teoh via Digitalmars-d wrote:
> >Wait, are you saying that forgetting the 'return' annotation will still compile without any warning?? Wow, that's ... not nice. :-(
> 
> Indeed, and the compiler will error out if you try that:
> 
> ---
> struct S {
>     int x;
> }
> 
> ref int foo(ref S s) {
>     return s.x;
> }
> ---
> 
> dmd -c foo -dip25
> foo.d(7): Error: escaping reference to local ref variable s
> 
> There'd be no point to DIP25 if it didn't.

Huh? We weren't talking about that -- it's already a given that this case works, otherwise DIP25 would truly have no point.

The problematic case comes from the manually-managed array member that you can freely return, yet it may become a dangling reference once opRelease deallocates it:

	class S {
		int[] data;
		int[] foo() { return data; } // <-- happily compiles
		void opAddRef() { ... }
		void opRelease() {
			...
			GC.free(data); // <-- uh oh
		}
	}

	int[] fun() {
		S s = /* create instance of S */
		return s.foo();
		// s goes out of scope here, and opRelease() cleans up
		// but we now have an escaping reference to s.data
	}

	void main() {
		int[] dangling = fun();
		dangling[0] = 1;	// kaboom
	}


S.foo() should have been annotated with 'return', but the programmer forgot and the compiler still accepts the code without any warnings, thereby violating @safe.


T

-- 
Bomb technician: If I'm running, try to keep up.
February 27, 2015
On 28 February 2015 at 01:43, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 2/27/15 7:17 AM, Manu via Digitalmars-d wrote:
>>
>> I'm not clear on structs. What is the order for calls; postblit, opInc, opDec, destructor? 75% of my use cases today are thin structs that wrap C/C++ api's.
>
>
> Structs don't get any special treatment with DIP74, only classes and interfaces.

Well this is the case of the highest value to me, and DIP74 offers nothing?
Can I call opAddRef/opRelease from within the postblit/destructor
manually and expect the compiler to elide calls correctly?
That doesn't seem foolproof though, and you also said manual calls are
not @safe. Why not specify a call sequence?


>> There's no mention of 'scope'. I presume functions that receive scope RC arguments will have the opportunity to have opAddRef/opRelesae elided around the call?
>
>
> That might be a future improvement. In fact that may be possible today; I've spoken to an ARC expert who read DIP74 and said Apple's ARC does not insert a retain() for a function call, i.e. it assumes functions only borrow unless they actually do keep a pointer (e.g. assign to a member or global), and only in that case inserts a retain().
>
> If I'm not missing something, we can do this with DIP74 which will reduce the opAddRef/opRelease traffic quite a bit.

Hmmm, that does sound right. Very nice.
February 27, 2015
On 2/27/15 7:42 AM, H. S. Teoh via Digitalmars-d wrote:
> S.foo() should have been annotated with 'return', but the programmer
> forgot and the compiler still accepts the code without any warnings,
> thereby violating @safe.

That is correct. However, the user is on the hook because her use of @trusted when deallocating the array.

I think the right thing to do about owned data is to give it its own abstraction, and plant it in the standard library. RCSlice would be an obvious go-to structure. Could you consider defining an OwnedSlice and see how far you can get?


Andrei

February 27, 2015
On 2/27/15 7:52 AM, Manu via Digitalmars-d wrote:
> Well this is the case of the highest value to me, and DIP74 offers nothing?

For structs you use postblit and destructors. -- Andrei
February 27, 2015
On 2/27/15 7:52 AM, Manu via Digitalmars-d wrote:
> Can I call opAddRef/opRelease from within the postblit/destructor
> manually and expect the compiler to elide calls correctly?
> That doesn't seem foolproof though, and you also said manual calls are
> not @safe. Why not specify a call sequence?

Ah, I think you mean structs that have a class member? The compiler will insert opAddRef and opRelease appropriately:

=========
* struct, class, and closure types that have RCO members accommodate calls to opRelease during their destruction.
=========


Andrei

February 27, 2015
On Fri, Feb 27, 2015 at 08:00:20AM -0800, Andrei Alexandrescu via Digitalmars-d wrote:
> On 2/27/15 7:42 AM, H. S. Teoh via Digitalmars-d wrote:
> >S.foo() should have been annotated with 'return', but the programmer forgot and the compiler still accepts the code without any warnings, thereby violating @safe.
> 
> That is correct. However, the user is on the hook because her use of @trusted when deallocating the array.
[...]

Which shows just how dangerous @trusted is. :-P  But that's a good point. The use of @trusted in theory should have raised red flags that the programmer needs to be careful here.  There's also the case of using malloc/free to allocate the array, but I suppose that falls in the same category.


T

-- 
A bend in the road is not the end of the road unless you fail to make the turn. -- Brian White
February 27, 2015
On 26/02/2015 22:04, Andrei Alexandrescu wrote:
> On 2/26/15 2:03 PM, Brian Schott wrote:
>> The DIP states that "Any attributes are allowed on these methods.", but
>> later states "The complexity of this code underlies the importance of
>> making opAddRef and especially opRelease nothrow". Should the DIP
>> require that these two functions be marked nothrow?
>
> It's a liberty still left to user code. -- Andrei

ISTM nothrow would be a sensible starting point. That would simplify compiler implementation and avoid invisible inefficiency in user code. Shouldn't we wait for a compelling use case for throwing in these functions before supporting it?
February 27, 2015
On 2/27/15 9:24 AM, Nick Treleaven wrote:
> On 26/02/2015 22:04, Andrei Alexandrescu wrote:
>> On 2/26/15 2:03 PM, Brian Schott wrote:
>>> The DIP states that "Any attributes are allowed on these methods.", but
>>> later states "The complexity of this code underlies the importance of
>>> making opAddRef and especially opRelease nothrow". Should the DIP
>>> require that these two functions be marked nothrow?
>>
>> It's a liberty still left to user code. -- Andrei
>
> ISTM nothrow would be a sensible starting point. That would simplify
> compiler implementation and avoid invisible inefficiency in user code.
> Shouldn't we wait for a compelling use case for throwing in these
> functions before supporting it?

I don't know of a compelling use case. Note that quite a few of the implementations complications remain; the surrounding code may still throw. -- Andrei

February 27, 2015
On 2/27/15 6:36 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Friday, 27 February 2015 at 08:26:14 UTC, Ola Fosheim Grøstad wrote:
>> On Thursday, 26 February 2015 at 22:04:09 UTC, Andrei Alexandrescu wrote:
>>> On 2/26/15 2:03 PM, Brian Schott wrote:
>>>>
>>>> One of the first things that stood out to me is that "add ref" is two
>>>> words and "release" is one. For the sake of symmetry, how about these:
>>>> *  opIncRef, opDecRef
>>>> *  opAcquire, opRelease
>>>
>>> All - please PLEASE do not derail this into yet another debate about
>>> which names are best. -- Andrei
>>
>> Using protocols rather than enforcing a particular implementation is
>> nice, but D needs to stop reinventing terminology and syntax matters.
>>
>> -- snip --
>
> AddRef/Release is established COM terminology.

One reason for keeping COM terminology might be if std.c.windows.com.IUnknown can automatically take advantage of DIP74. Of course this could also be a downside—would DIP74 break existing COM code in D?