const(Rvalue) resolved to different overloads

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Thu Dec 29 23:59:13 PST 2016


On Thursday, December 29, 2016 14:54:35 Ali Çehreli via Digitalmars-d wrote:
> I'm working on understanding how different qualifiers of the same type,
> the kinds of indirections that its members may have, and the expressions
> being lvalue versus rvalue affect function overload resolution.
>
> For example, the following program has
>
> - struct S with a member having const indirection
>
> - Two overloads of the same function taking S and immutable(S)
>
> - Two calls made with an Rvalue and a const Rvalue
>
> import std.stdio;
>
> struct S {
>      const(int)[] a;
> }
>
> void foo(S s) {
>      writefln("foo(S) called");
> }
>
> void foo(immutable(S) s) {
>      writefln("foo(immutable(S)) called");
> }
>
> void main() {
>      writefln("calling with Rvalue");
>      foo(S());
>
>      writefln("calling with const Rvalue");
>      foo(const(S)());
> }
>
> The peculiar thing is that the const Rvalue case is resolved to the
> immutable(S) overload:
>
> calling with Rvalue
> foo(S) called
> calling with const Rvalue
> foo(immutable(S)) called    <-- ?
>
> Can you explain that behavior?
>
> Well... I already see that for that to happen, the argument must have
> the S.init value (or be constructed explicitly as const(S)(null)). When
> initialized with something else, it is resolved to the foo(S) overload:
>
>      const(int)[] a = [ 42 ];
>      foo(const(S)(a));
>
> calling with const Rvalue
> foo(S) called               <-- Now different; surprising
>
> Bug or not? If not, then I don't think there can ever be more than a
> total of about 0.75 people who fully know D overload resolution. :o)

I very much doubt that it's a bug, since it seems like the sort of thing
that would require extra logic to make happen. That being said, I think that
an argument could definitely be made that it was a bad decision from the
standpoint of consistency (and it's quite possible that it's an accident
that it works the way it does thanks to some weird combination of features).
It wouldn't entirely surprise me though if the current behavior is a result
of someone wanting a particular piece of code to work that wouldn't work
otherwise. In practice, I wouldn't expect it to matter - and usually if
you've overloaded on mutable and immutable, you're going to want to overload
on const as well anyway - but the current behavior does make it entertaining
to figure out what's going to happen in corner cases, which isn't exactly a
good thing and goes counter to a lot of the reasoning behind why D's
overloading rules generally work the way they work.

- Jonathan M Davis




More information about the Digitalmars-d mailing list