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

Reply via email to