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