Why can't we make reference variables?
Era Scarecrow
rtcvb32 at yahoo.com
Wed Aug 29 07:17:20 PDT 2012
On Wednesday, 29 August 2012 at 12:41:26 UTC, Tommi wrote:
> I think we might be talking about somewhat different things.
> What I mean by reference variable is what the term means in
> C++. From wikipedia:
> http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29
>
> C++ references differ from pointers in several essential ways:
>
> * It is not possible to refer directly to a reference object
> after it is defined; any occurrence of its name refers directly
> to the object it references.
>
> * Once a reference is created, it cannot be later made to
> reference another object; it cannot be reseated. This is often
> done with pointers.
>
> *References cannot be null, whereas pointers can; every
> reference refers to some object, although it may or may not be
> valid. Note that for this reason, containers of references are
> not allowed.
>
> * References cannot be uninitialized. Because it is impossible
> to reinitialize a reference, they must be initialized as soon
> as they are created. In particular, local and global variables
> must be initialized where they are defined, and references
> which are data members of class instances must be initialized
> in the initializer list of the class's constructor. For
> example: int& k; // compiler will complain: error: `k' declared
> as reference but not initialized
Then most of my examples change to going into the constructor
rather than out, and the global one goes away. But it still
doesn't help with the problem of anything stack allocated.
struct S {
//default construtor otherwise then fails to work because of
ref? Since
//x must be known at compile time so it would be null to start
with, or no
//default onstructor
ref int x;
this(ref int r) { x = r;}
}
S func() {
int local = 42;
S s = S(local);
return s;
}
S func(ref int reffed) {
S s = S(reffed);
return s;
}
S s = func();
writeln(s.x); //mystery value still!
{
int local = 42;
s = func(local);
writeln(s.x); //42
}
writeln(s.x); //!?!?
Unless I'm understanding this wrong (And I'm tired right now
maybe I missed something), once again the only safe 'reference
variable' is from actively being called from a live accessible
reference; And anything else is still a ticking timebomb and
cannot ever be @safe. Stuff referencing within heaped/class
related stuff may suffer fewer problems, but only as long as you
rely on the GC and not do any magic involving malloc/free, or
maybe a dynamic range.
Reminds me. The example for the foreach are missing parts.
int[10] fixed;
int[] dynamic;
dynamic.length = 10;
foreach(i; fixed) {
//fine, i is a copy
}
foreach(ref i; fixed) {
//compile-time error for @safe checking
//cannot ensure this is safe otherwise
}
foreach(i; dynamic) {
//fine, i is a copy
}
foreach(ref i; dynamic) {
//Dynamic/heap allocated, so fine.
}
//from function/ref
void func(int[] huh) {
foreach(ref i; huh) {
//????? safe?
}
}
//both legal last I checked.
func(fixed);
func(dynamic);
My god, as I look at this more, reference variables would
cripple D so badly C++ wouldn't look half bad afterwards.
More information about the Digitalmars-d
mailing list