pointers, functions, and uniform call syntax

Era Scarecrow rtcvb32 at yahoo.com
Tue Sep 4 11:19:42 PDT 2012


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); }


More information about the Digitalmars-d mailing list