Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Occurs compilation error in overload with extern(Windows) #3362

Open
kntroh opened this issue Mar 13, 2020 · 5 comments
Open

Occurs compilation error in overload with extern(Windows) #3362

kntroh opened this issue Mar 13, 2020 · 5 comments

Comments

@kntroh
Copy link

kntroh commented Mar 13, 2020

dmd 2.091.0 passes this code, but ldc 1.20.1 occurs an compilation error:

extern (Windows) {
    // test.d(7): Error: Function type does not match previously declared function with the same mangled name: func1
    // test.d(7):        Previous IR type: void (i32)
    // test.d(7):        New IR type:      void (i8*)
    void func1(ptrdiff_t);
    void func1(void*);
}

func1 is included in another object file, Can be linked and run with dmd.

$ cat func1.d
extern (Windows) void func1(ptrdiff_t t) {
    import core.stdc.stdio;
    printf("%d\n", t);
}
$ dmd func1.d -c
$ cat test.d
extern (Windows) {
    void func1(ptrdiff_t);
    void func1(void*);
}
void main() {
    func1(null);
    func1(0);
}
$ dmd func1.obj -run test.d
0
0
$

I don't know which is correct, dmd or ldc. Should this be an incorrect code?

I found this problem while compiling dwt. This code:

 LRESULT SendMessageW(HWND, UINT, WPARAM, LPARAM);
 LRESULT SendMessageW(HWND, UINT, WPARAM, void*);
 LRESULT SendMessageW(HWND, UINT, void*, LPARAM);
 LRESULT SendMessageW(HWND, UINT, void*, void*);

dwt can be used without any problems with dmd.

@JohanEngelen
Copy link
Member

Try compiling this code and look at compiler output:

extern (Windows) {
    void func1(ptrdiff_t);
    pragma(msg, func1.mangleof);
    void func2(void*);
    pragma(msg, func2.mangleof);
}

Outputs:

func1
func2

In other words: the function arguments are not part of the function name in the executable (C-style mangling). This means that the executable does not distinguish between calls to your void func1(ptrdiff_t) and void func1(void*), both point to the same function. Multiple functions with the same name but different argument types are of course very dangerous, so I think LDC is correct here in rejecting the code.

@kntroh
Copy link
Author

kntroh commented Mar 13, 2020

Multiple functions with the same name but different argument types are of course very dangerous, so I think LDC is correct here in rejecting the code.

I think so too. Is this omission of the dlang specification?

@kinke
Copy link
Member

kinke commented Mar 13, 2020

Ideally, this would be a frontend error, clearly stating that there's no such thing as overloads for C functions. But because people tend to re-declare external C[++] structs in different modules/libraries, the current DMD behavior is sadly expected, see #2782.

@kntroh
Copy link
Author

kntroh commented Mar 13, 2020

I looked at the behavior of dmd, I think it is bug (of spec or compiler).
It is completely wrong that this code can be compiled:

extern (C) {
    void func(int);
    void func(double, double);
    void func(char[42]);
}

I'll report to dmd.

@kntroh
Copy link
Author

kntroh commented Mar 13, 2020

I reported it: https://issues.dlang.org/show_bug.cgi?id=20672

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants