Comment #0 by bearophile_hugs — 2010-10-17T05:21:22Z
This is a wrong D2 program:
import std.c.stdlib: qsort;
import std.c.stdio: printf;
int compare(const void *a, const void *b) {
return *cast(int*)a - *cast(int*)b;
}
void main () {
int[] values = [40, 10, 100, 90, 20, 25];
for (int n = 0; n < 6; n++)
printf ("%d ", values[n]);
printf("\n");
qsort(values.ptr, 6, int.sizeof, &compare);
for (int n = 0; n < 6; n++)
printf ("%d ", values[n]);
printf("\n");
}
With DMD 2.049 it compiles with no errors, and then sefaults at runtime.
To fix it the compare() must have a C calling convention:
extern(C) int compare(const void *a, const void *b) {
DMD 1.026 avoids that runtime error with a useful compile-time error message that I'd like in DMD2 too:
Line 15: function std.c.stdlib.qsort (void*,uint,uint,int(C *)(void*, void*)) does not match parameter types (int*,int,uint,int(*)(void*, void*))
Line 15: Error: cannot implicitly convert expression (& compare) of type int(*)(void*, void*) to int(C *)(void*, void*)
A better single error message for D2 may say "extern(C)" too somewhere in the error message, instead of just saying a less clear "expression (& compare) of type int(*)(void*, void*) to int(C *)(void*, void*)". Something like:
Line 15: Error: cannot implicitly convert expression (& compare) of type int function(const void*, const void*) to extern(C) int function(const void*, const void*)
*** This issue has been marked as a duplicate of issue 3797 ***
Comment #3 by bearophile_hugs — 2011-09-02T04:01:25Z
With this fix:
https://github.com/D-Programming-Language/dmd/commit/306df8eaa6f8a987f76f401a1e03d8edf1f1e2ae
Now DMD prints:
test.d(15): Error: function core.stdc.stdlib.qsort (void* base, uint nmemb, uint size, int C function(in const(void*), in const(void*)) compar) is not callable using argument types (int*,int,uint,int function(in const(void*), in const(void*)))
test.d(15): Error: cannot implicitly convert expression (& compare) of type int function(in const(void*), in const(void*)) to int C function(in const(void*), in const(void*))
Instead of:
int C function(in const(void*), in const(void*))
I think this allows to see the C better:
int extern(C) function(in const(void*), in const(void*))
Comment #4 by yebblies — 2011-09-02T06:15:22Z
(In reply to comment #3)
> With this fix:
> https://github.com/D-Programming-Language/dmd/commit/306df8eaa6f8a987f76f401a1e03d8edf1f1e2ae
>
> Now DMD prints:
>
> test.d(15): Error: function core.stdc.stdlib.qsort (void* base, uint nmemb,
> uint size, int C function(in const(void*), in const(void*)) compar) is not
> callable using argument types (int*,int,uint,int function(in const(void*), in
> const(void*)))
> test.d(15): Error: cannot implicitly convert expression (& compare) of type int
> function(in const(void*), in const(void*)) to int C function(in const(void*),
> in const(void*))
>
>
> Instead of:
> int C function(in const(void*), in const(void*))
>
> I think this allows to see the C better:
> int extern(C) function(in const(void*), in const(void*))
I agree. Is there an enhancement request already open for this?
Comment #5 by bearophile_hugs — 2011-09-02T10:13:59Z
(In reply to comment #4)
> I agree. Is there an enhancement request already open for this?
bug 6596