On Monday, 22 April 2013 at 13:17:36 UTC, Namespace wrote:
On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
I realise I'm new here but this seems to be suggesting a whole
load of changes and special cases for something that can be
done in (IMHO) a much simpler way:
Why not simply make escaping a "ref" pointer an unsafe
operation. The compiler should be able to detect this and
report it without any changes to the syntax.
This should cover 99% of cases with no extra attributes
required and no limitations on what you can do with a "ref"
within the function. In the 1% of cases that a pointer needs
to be escaped safely you can add an attribute (maybe "heap
ref" or something, although perhaps some existing syntax could
be used) that requires the input to have been allocated on the
heap.
In the case that a stack variable is passed as a "heap ref"
parameter the compiler can automatically promote it where
possible, or if that's not possible, such as the variable
being marked "scope" (existing meaning) then it should
complain.
All values (including literals and temporaries) should then be
able to be passed to a "ref const" parameter.
As far as I'm aware the only real purpose for R-value
references is to implement move semantics. This could already
be done using "ref in" syntax, as that makes no guarantees
that the value is not going to be destroyed, only says that
the value should be initialised prior to it being passed in.
The only change would be to allow passing temporaries as "ref
in".
To promise that the variable is not going to be modified "ref
const" or "ref const in" can be used.
This DIP already suggest 'in ref' besides 'scope ref'. 'in' is
a shortcut for const scope.
And Andrei already reject variants which _only_ consist of
non-mutable rvalue ref's (like const ref), because the const
system in D is physical.
The definition was somewhat hidden in the language reference and
the first reference I found on the forum said that "in" simply
meant that the value should be initialised by the caller (in the
same way that "out" means that the callee initialises the value).
But this could be read on the wiki. You should read the DIP
before you write here. ;)
I have but the DIP isn't consistent, for example in test1 it says
R-value temporaries are allowed:
void test1(scope ref A a)
And in test32 it says they are not "Only adressable parameters
are valid, not temporaries, no extra template instances.":
void test32(T)(scope ref T id)
And then:
test32(1337); // Fine, temporary mutable int variable is
created with value 1337
Some other problems:
- Taking the address of a "scope ref" variable is prohibited even
if the compiler can prove that it's safe.
- Implementing "forward" in the following is impossible:
doSomething(forward(<temporary/literal>))
Obviously a function that simply returns what is passed in seems
pointless but it may be very useful if sometimes that function
should do something else.
All the restrictions on "scope ref" are exactly the same as the
restrictions on "ref" if DIP25 is implemented, except that "scope
ref" variables can't be returned (why is this the case when by
following the same rules as DIP25 it can be safe?)
In which case why not allow passing R-value references as normal
"ref" parameters? Why the need for "scope" when the only new
restriction it introduces can (and should) be avoided.
DIP25 says that the return value of a ref function must not be
assumed to have a lifetime longer than the shortest lifetime of
any of its ref parameters. This formulation works just as well
for an R-value reference as it does for a reference to a local
variable, just that the first is slightly shorter.