On Friday, 27 February 2015 at 21:21:08 UTC, Andrei Alexandrescu
wrote:
On 2/27/15 1:02 PM, Michel Fortin wrote:
On 2015-02-27 20:34:08 +0000, Steven Schveighoffer said:
On 2/27/15 3:30 PM, Steven Schveighoffer wrote:
void main()
{
C c = new C; // ref counted class
C2 c2 = new C2; // another ref counted class
c2.c = c;
foo(c, c2);
}
Bleh, that was dumb.
void main()
{
C2 c2 = new C2;
c2.c = new C;
foo(c2.c, c2);
}
Still same question. The issue here is how do you know that
the
reference that you are sure is keeping the thing alive is not
going to
release it through some back door.
You have to retain 'c' for the duration of the call unless you
can prove
somehow that calling the function will not cause it to be
released. You
can prove it in certain situations:
- you are passing a local variable as a parameter and nobody
has taken a
mutable reference (or pointer) to that variable, or to the
stack frame
(be wary of nested functions accessing the stack frame)
- you are passing a global variable as a parameter to a pure
function
and aren't giving to that pure function a mutable reference to
that
variable.
- you are passing a member variable as a parameter to a pure
function
and aren't giving to that pure function a mutable reference to
that
variable or its class.
There are surely other cases, but you get the idea. These three
situations are probably the most common, especially the first
one. For
instance, inside a member function, 'this' is a local variable
and you
will never pass it to another function by ref, so it's safe to
call
'this.otherFunction()' without retaining 'this' first.
Thanks. So it seems we continue as we were with DIP74 and leave
the rest to the implementation.
Andrei
Still seems like a very significant performance penalty for such
a strange case. It probably won't surprise you that I would
suggest another parameter attribute to the rescue,
e.g.`@rcRelease`! Inter-function communication for the win!