Why can't we make reference variables?
Era Scarecrow
rtcvb32 at yahoo.com
Wed Aug 29 05:00:06 PDT 2012
On Wednesday, 29 August 2012 at 04:54:31 UTC, Tommi wrote:
> On Wednesday, 29 August 2012 at 03:17:39 UTC, Era Scarecrow
>> I think that's right; Otherwise ref wouldn't be allowed in
>> @safe code (at all).
>
> But couldn't the compiler disallow all unsafe ref use in @safe
> code, and allow all use of ref in @system and @trusted code?
So.... Ref can only then be used if it's heap allocated... That
would be the only @safe way, but even that is ridden with
timebombs.
int[10] xyz;
foreach(i; xyz) {
//all's good, they are copies!
}
foreach(ref i; xyz) {
// cannot use ref, (not even const ref) as it may be unsafe
}
//a ref function
void func(ref int i);
int *z = new int;
func(z); //or is it *z? 'Might' be good
func(xyz[0]); //Compile error, may be unsafe.
class C {
int cc;
}
struct S {
int sc;
}
C cSomething = new C();
S sSomething = S();
S* sSomething2 = new S();
func(cSomething.cc); //good, heap allocated enforced
func(sSomething.sc); //error, may be unsafe!
func(sSomething2.sc); //pointer dereference; It bypasses
protections since it probably is heap (but not guaranteed), so
maybe this should fail too.
sSomething2 = &sSomething;
func(sSomething2.sc); //back to a timebomb situation but the
compiler can't verify it! only something from a class could be
considered safe (maybe)
Why is it unsafe? Let's assume we did this:
ref int unsafe; //global ref. Hey it's legal if ref is allowed
as you want it!
void func(ref int i) {
unsafe = i;
}
Now I ask you. If any of the 'unsafe' ones were used and then
the scope ended that held that information and we use unsafe now,
it can only be a time bomb: All of them stem from them being on
the stack.
void someFunc() {
int stacked = 42;
func(stacked);
}
someFunc();
writeln(unsafe); //what will this print? Will it crash?
//some scope. FOR loop? IF statement? who cares?
{
int local = 42;
func(&local); //assuming the pointer bypasses and gets
dereferenced to get past the heap only compiler problems
(pointers and classes only) limitations
writeln(unsafe); //prints 42 as expected
}
writeln(unsafe); //????? Scope ended. Now what? can't ensure
local exists anymore as we reffed a stack
class Reffed {
ref int i;
}
//some scope
Reffed r = new Reffed();
Reffed r2 = new Reffed();
@trusted {
int local;
r.i = local; //may or may not work normally, @trusted should
force it
}
//Why not copy a reference from a class?
//it should be good (heap only), right?
r2.i = r.i;
writeln(r.i); //?????
writeln(r2.i); //?!?!
To make it 'safe' the only way to do it is ref can only be used
on heap allocated data (or global fixed data). The current
implementation as I see it anything referenced is safe because
you can only reference something that currently exists (via
function calls).
The other way to make it safe is to silently include a flag that
specifies if it was stack allocated or not, but even that becomes
more complicated and more of an issue.
More information about the Digitalmars-d
mailing list