D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5069 - No missing extern(C) error
Summary: No missing extern(C) error
Status: RESOLVED DUPLICATE of issue 3797
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: accepts-invalid, diagnostic
Depends on:
Blocks:
 
Reported: 2010-10-17 05:21 UTC by bearophile_hugs
Modified: 2011-09-02 10:13 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-10-17 05:21:22 UTC
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*)
Comment 1 yebblies 2010-10-17 06:59:01 UTC
Related to http://d.puremagic.com/issues/show_bug.cgi?id=3797
Comment 2 anonymous4 2010-10-18 10:58:09 UTC

*** This issue has been marked as a duplicate of issue 3797 ***
Comment 3 bearophile_hugs 2011-09-02 04:01:25 UTC
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 yebblies 2011-09-02 06:15:22 UTC
(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 bearophile_hugs 2011-09-02 10:13:59 UTC
(In reply to comment #4)

> I agree.  Is there an enhancement request already open for this?

bug 6596