pointers, functions, and uniform call syntax

Era Scarecrow rtcvb32 at yahoo.com
Mon Sep 3 13:04:56 PDT 2012


On Monday, 3 September 2012 at 18:45:42 UTC, Jonathan M Davis 
wrote:
> However, one thing to remember that complicates this a bit is 
> that it's perfectly possible to declare a function which is 
> overloaded with one function taking a pointer and one not.
>
> void func(S* s, int i) {...}
> void func(S s, int i) {...}
>
> in which case, there's an ambiguity, and I would then expect 
> UFCS to _not_ compile when using S*, or you'd risk function 
> call hijacking. That's not necessarily a big deal, but it 
> _does_ complicate things a bit.
>
> - Jonathan M Davis

  I think moreso is would if it would convert to ref automatically 
or not rather than worry about pointers. True if you wanted all 
three, then the language has to keep them all distinctly 
different; But if it silently converts it should be okay (so long 
as constness/immutable is honored). Assuming that's the case:

   //these two effectively identical
   void func(S* s, int i) {...}
   void func(ref S s, int i) {...}

I can see allowing a pointer be silently converted to a reference 
safely, however a normal to a pointer not so easily, not so much 
for type safety but accidents could be prone to happen. So...

   void funcP(S* s) {...}
   void funcR(ref S s) {...}

   struct S{}

   S *sp; //pointer
   S ss;  //stack

   funcP(sp); //obviously will work fine
   funcP(ss); //error, pointer conversion may be confused for heap 
allocation
   funcR(sp); /*silently converting is acceptable as long
                as const/immutable is honored */
   funcR(ss); //normal use as is used now.

  The reason it could be allowed as ref and not a pointer is the 
same as the argument for if you can have ref variables. If it's 
part of the function calling signature, you're guaranteed it's a 
live/valid item being passed, but a pointer would be required if 
it was a member item.

  However silently converting may have the result where functions 
using ref may suddenly have new issues if you can have a null 
reference (not normally possible), and it's impossible to check.

   S *p; //we know it's null
   funcR(p); //silently converts

   void funcR(ref S s)
   in{
     //can't check for a null reference! It's not a pointer!
   }
   body {
     //time bomb with odd error when used?
   }

  Currently if I have it right, it would break if the object was 
invalid (during dereference/copying); You would have a more 
accurate error message that way (I'm certain).


  As a workaround you can have both functions and one call/convert 
to the other for you. With the workaround being this simple/small 
it's a very small price to pay; I would say automatically 
converting a pointer to a reference is likely something to be 
discussed; But I honestly would be against it for safety reasons.

   //maybe a ref or const versions as appropriate.
   void func(S s, int i) {...}

   //pointers should be the same (in my code) so here's my 
workaround!
   void func(S *s, int i) {
     func(*s, i);
   }


More information about the Digitalmars-d mailing list