Problem of undefined behaviour with overloaded methods and overloaded delegate's invokers
John Colvin via Digitalmars-d
digitalmars-d at puremagic.com
Tue Aug 1 04:30:07 PDT 2017
On Tuesday, 1 August 2017 at 11:07:59 UTC, knex wrote:
> I came across a strange thing and I am not sure if this is a
> bug or just an undefined behaviour of a compiler. Here is some
> sample code to present the case:
>
> //
>
> alias BoolFirst = void delegate(bool b, string s);
> alias StringFirst = void delegate(string s, bool b);
>
> class Caller {
> void call(BoolFirst bs) { bs(true, "text"); }
> void call(StringFirst sb) { sb("text", true); }
> }
>
> class Writer {
> import std.stdio;
> void write(bool b, string s) { writeln("bool+string:", b,
> "/", s); }
> void write(string s, bool b) { writeln("string+bool:", s,
> "/", b); }
> }
>
> void main() {
> new Caller().call(&new Writer().write);
> }
>
> //
>
> As you can see, I have two classes, both having two overloaded
> methods. Writer has some dummy printing methods for bool and
> string, differing with the order of the arguments, while Caller
> takes one of these methods as a delegate and invokes it. In
> main() I create objects of these classes and call Caller's
> call() with Writer's write().
>
> But - as far as I understand - this call is ambiguous, and
> compiler does not know what should be done here: calling
> call/write pair for bool+string or for string+bool parameters.
> Nevertheless the code compiles and the program runs the fist
> variant. The funny thing is that swapping write() methods in
> the source file causes calling the second one. But OK, suppose
> that this is and should be treated as an undefined behaviour.
> What is actually disturbing here, is that casting like
> c.call(cast(BoolFirst) &w.write) compiles, although is not
> necessary, because not casting works the same way, but casting
> c.call(cast(StringFirst) &w.write) - which should help here in
> calling string+bool variant - does not compile, and the
> compiler says that "Caller.call called with argument types
> (void delegate(string s, bool b)) matches both (...)", which is
> clearly true. Moreover, swapping write() methods again causes
> the exact opposite behaviour: cast(StringFirst) compiles, but
> is useless, and cast(BoolFirst) does not compile at all.
>
> So, is this a bug, or am I just not getting something? In the
> first case, is there some kind of a workaround for the
> possibility of calling both variants (without changing the code
> of Caller and Writer classes)? In the last case, how should I
> do it properly?
>
> I am using DMD32 D Compiler v2.075.0 on Linux.
looks like a bug to me. Please report at issues.dlang.org
More information about the Digitalmars-d
mailing list