[Issue 16414] New: final opCmp in interface: throws at runtime. (OK if abstract class instead of interface)

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Mon Aug 22 03:06:58 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=16414

          Issue ID: 16414
           Summary: final opCmp in interface: throws at runtime. (OK if
                    abstract class instead of interface)
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: eiderdaus at gmail.com

The following code compiles, but throws at runtime.
Stack trace is at end of post.
I use dmd v2.071.2-b2 on Debian 6.

    import std.stdio;
    import std.algorithm;

    interface IA {
        @property int val();
        final int opCmp(IA rhs) { return val - rhs.val; }
    }

    class A : IA {
        private int _val;
        this(int i) { _val = i; }
        @property int val() { return _val; }
    }

    void main()
    {
        A[] as = [ new A(3), new A(2) ];
        as.sort();
        foreach (a; as)
            writeln(a.val);
    }

=============================================================================

When I change A[] to IA[], i.e., change the first line of main() to this:

    IA[] as = [ new A(3), new A(2) ];

...then everything still builds, and doesn't throw. The runtime finds the
final opCmp in IA and uses it. The sorted output is 2, then 3.

Another workaround: Change the interface into an abstract class:

    abstract class IA {
        abstract @property int val();
        final int opCmp(IA rhs) { return val - rhs.val; }
    }

Sorting an array of (class A : AI) will then never throw, no matter whether
I declare the array as A[] or as AI[].

=============================================================================

Runtime-thrown trace for the original code:

object.Exception at src/object.d(90): need opCmp for class testinterfaceopcmp.A
----------------
??:? int object.Object.opCmp(Object) [0x441fd9]
??:? bool std.functional.binaryFun!("a < b", "a",
"b").binaryFun!(testinterfaceopcmp.A, testinterfaceopcmp.A).binaryFun(ref
testinterfaceopcmp.A, ref testinterfaceopcmp.A) [0x440918]
??:? void
std.algorithm.sorting.__T23optimisticInsertionSortS773std10functional49__T9binaryFunVAyaa5_61203c2062VAyaa1_61VAyaa1_62Z9binaryFunTAC18testinterfaceopcmp1AZ.optimisticInsertionSort(testinterfaceopcmp.A[])
[0x441540]
??:? void
std.algorithm.sorting.__T13quickSortImplS773std10functional49__T9binaryFunVAyaa5_61203c2062VAyaa1_61VAyaa1_62Z9binaryFunTAC18testinterfaceopcmp1AZ.quickSortImpl(testinterfaceopcmp.A[],
ulong) [0x440b73]
??:?
std.range.__T11SortedRangeTAC18testinterfaceopcmp1AVAyaa5_61203c2062Z.SortedRange
std.algorithm.sorting.sort!("a < b", 0,
testinterfaceopcmp.A[]).sort(testinterfaceopcmp.A[]) [0x4403fc]
??:? _Dmain [0x4400ab]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x443a7e]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).tryExec(scope void delegate()) [0x4439c8]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).runAll() [0x443a3a]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).tryExec(scope void delegate()) [0x4439c8]
??:? _d_run_main [0x443939]
??:? main [0x441f09]
??:? __libc_start_main [0x136c8cac]

--


More information about the Digitalmars-d-bugs mailing list