Bug 12872 – Feature request: Allow ref in arguments at the callsite
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2014-06-06T21:25:41Z
Last change time
2021-06-16T13:25:43Z
Assigned to
No Owner
Creator
Brad Anderson
Comments
Comment #0 by eco — 2014-06-06T21:25:41Z
It'd be nice to be able to do this...
void foo(ref int a)
{
a += 1;
}
void main()
{
int a;
foo(ref a) // <---- callsite ref
}
...to show that a reference is being taken during that call and that the value may change within the function call.
I think it would also be nice if you could require the callsite ref using a compiler switch and that it would eventually be on by default (I suspect this is far more controversial though and should be considered a separate request from just allowing the "ref" in the call).
The same extends to "out". "in" could be added too but I don't see much value in that.
Comment #1 by bearophile_hugs — 2014-06-06T22:07:39Z
People keep asking for this feature from the C# language, and it keeps being shot down. This is becoming the most commonly refused enhancement request for D.
Comment #2 by issues.dlang — 2014-06-07T01:58:04Z
While I understand the motivation behind this, it really doesn't make sense.
1. It's essentially pointless unless it's required that ref be at the call site, otherwise while ref at the call site then tells that that argument is accepted by ref, it tells you _nothing_ about any argument that isn't marked with ref - maybe it's being passed by ref, and maybe it isn't. So, you still have to look at the documentation or function signature in order to determine whether a function is accepting a particular argument by ref or not. So, ref would need to be required at the call site for this to make sense. Making this change would be a breaking change, and I very much doubt that Walter would go for it at this point - particularly when at one point, he was considering having ref accept rvalues once the safety checks for ref that were being discussed at the time were put in place, and accepting rvalues is going in the complete opposite direction of this enhancement request.
2. Even if we could made the changes, they would _not_ play nicely with UFCS. There's nowhere to place the ref at the call site when the argument is being used with UFCS.
If the concern is that we want it to be explicit when passing by reference or pointer, and passing by pointer is undesirable because taking the address of a local variable forces the caller to then be @system or @trusted, then I think that we would be better served by doing something with scope that made it so that if the pointer parameter were scope, and you took the address of a local variable to pass to it directly, then it would be @safe, because the compiler could guarantee that the pointer wasn't escaping.
Comment #3 by eco — 2014-06-07T03:00:55Z
> 1. It's essentially pointless unless it's required that ref be at the call site, otherwise while ref at the call site then tells that that argument is accepted by ref, it tells you _nothing_ about any argument that isn't marked with ref - maybe it's being passed by ref, and maybe it isn't. ...
I agree that without enforcement this enhancement request is less useful than it could be but it is still beneficial for at least two things:
- Self documenting the code. Even if just optional it'd be nice to see at a glance that a reference is being taken. Sure, you could add /* passed by ref */ in there but it's noisier than it needs to be.
- Error when the callsite ref disagrees with the function. If you've called with ref but the function doesn't accept ref then you've made an obvious error and should be told about it. This is very similar to the override keyword which is genuinely useful and catches real bugs. This wouldn't be a breaking change so it'd be safe to enforce.
> 2. Even if we could made the changes, they would _not_ play nicely with UFCS.
Yeah, and that's the first thing I thought of that would be a problem with enforcing it and one of the reasons I'm not requesting enforcement with this enhancement request, only mentioning that it could be done in the future potentially.
> ...doing something with scope...
I'd love for this to happen (I wish reference types were scope by default personally). I don't think scope pointers should just replace `out` though.
Side rant: If we had warning levels like every other compiler in existence than we could have people opt into an enforcement warning for this but I don't think Walter will budge on that. :(
Comment #4 by pro.mathias.lang — 2021-06-16T06:05:27Z
I also would like to see this, however, as it stands, this would have to go through the DIP process to make it into the language. Closing as it's not a bug and is not actionable.
Comment #5 by apz28 — 2021-06-16T13:24:20Z
Actual benefit is for variadic arguments function call. For this case, it allows callside to specify how argument to be passed. This also allow to create generic template to define delegate/event
void print(A...)(A a)
or
struct DelegateList(Args...)
{
alias DelegateHandler = void delegate(Args args);
DelegateHandler[] items;
void opCall(Args args)
{
foreach (i; items)
i(args);
}
}
Comment #6 by apz28 — 2021-06-16T13:25:43Z
Actual benefit is for variadic arguments function call. For this case, it allows callside to specify how argument to be passed. This also allow to create generic template to define delegate/event
void print(A...)(A a)
or
struct DelegateList(Args...)
{
alias DelegateHandler = void delegate(Args args);
DelegateHandler[] items;
void opCall(Args args)
{
foreach (i; items)
i(args);
}
}