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