On Tuesday, 4 September 2012 at 10:51:36 UTC, Artur Skawina wrote:
On 09/03/12 20:45, Jonathan M Davis wrote:

It's a  perfectly valid enhancement request to want

void func(S s, int i) {...}

to be be callable with S*, given that normally function calls on an S* don't require you to dereference anything.

No, it's not. See http://d.puremagic.com/issues/show_bug.cgi?id=8490 for why
this would be a very bad idea. However 'void func(ref S s, ...){}' should (be made to) work, at least for the UFCS case - if it already doesn't (old compiler here...) - if 'func' is supposed to emulate a method then it should behave like one.

Hmmm... And here i consider the opposite true. With ref as it works, you can only pass 'live' (absolutely guaranteed to be allocated) variables to work, you can't guarantee that with a normal pointer.

 On the other hand. Let's consider the two calls.

  struct S {
    int x, y;
    int gety(){ return y;}
  }

  int getx(S s) {return s.x;}

  S ss;
  S *sp = &ss; //without errors for now

  writeln(ss.gety());
  writeln(sp.gety()); /*pointer but as it currently works,
                        the same (technically) */

  writeln(ss.getx());
  writeln(sp.getx()); //currently breaks without dereferencing

If getx is valid with a pointer, it will be more consistent (and doesn't change anything). Now let's void it.

  sp = null;

  writeln(sp.gety()); //null pointer, refers to calling site
  writeln(sp.getx()); /*null pointer, breaks during copying and
                        should refer to calling site*/

This I think is totally acceptable since it would be the same error and the same reason. If we take ref and allow that, you may as well allow referencing variables (and not just in the function signature)

  struct S {
    //may as well allow during building of struct,
    //it's just as safe as the rest of the ref calls now.
    ref S prev;  //defaults to null
    this (ref S s) {prev = s};

    int x;
  }

  int getx(ref S s) {return s.x}

  //now breaks inside getx
  writeln(sp.getx());
  writeln(getx(sp));

  //might compile?; More likely it's no longer a named variable
  writeln((*sp).getx());
  writeln(getx(*sp));

  //might compile, but now it's old C/C++ pointers. Very risky?
  writeln(getx(sp[0]));

 I ask you, how do you check if it's a null pointer? &s?

  int getx(ref S s)
  //How does this make sense?? it looks wrong and is misleading
  in {assert(&s); }
  body {return s.x); }

More importantly, if it's now a possibility do we have to start adding checks everywhere?

  int getx(S *s)
in {assert(s); } //perfectly acceptable check, we know it's a pointer
  body {return s.x); }

Reply via email to