On 2015-03-03 22:39:12 +0000, Michel Fortin said:

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.

And giving it some more thought, @refbreaking also has the interesting property that any pair of opAddRef/opRelease with no @refbreaking call between them can be elided safely.

--
Michel Fortin
[email protected]
http://michelf.com/

Reply via email to