RCArray is unsafe

Michel Fortin via Digitalmars-d digitalmars-d at puremagic.com
Tue Mar 3 14:39:12 PST 2015


On 2015-03-02 05:57:12 +0000, Walter Bright said:

> On 3/1/2015 12:51 PM, Michel Fortin wrote:
>> That's actually not enough. You'll have to block access to global 
>> variables too:
> 
> Hmm. That's not so easy to solve.

Let's see. The problem is that 'ref' variables get invalidated by some 
operations. Perhaps we could just tell the compiler that doing this or 
that will makes 'ref' variables unsafe after that point. Let's try 
adding a @refbreaking function attribute, and apply it to 
RCArray.opAssign:

	S s;

	void main() {
		s.array = RCArray!T([T()]);
		foo(s.array[0]);
	}
	void foo(ref T t) {
		t.doSomething(); // all is fine
		s.array = RCArray!T([]); // here, RCArray.opAssign would be labeled 
@refbreaking
		t.doSomething(); // cannot use 'ref' variable after doing a 
refbreaking operation
	}

Also, the above shouldn't compile anyway because @refbreaking would 
need to be transitive, and it follows that `foo` would need to be 
@refbreaking too:

	void foo(ref T t) @refbreaking {
		...
	}

which in turn means that `main` too needs to be @refbreaking.

So what needs to be @refbreaking? Anything that might deallocate. This 
includes `opRelease` if it deallocates when the counter reaches zero. 
Although you could implement `opRelease` in a way that sends the memory 
block to an autorelease pool of some kind, in which case draining the 
autorelease pool at a later point would be @refbreaking.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list