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