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

Issue with opaque struct across modules #3817

Closed
p0nce opened this issue Aug 17, 2021 · 8 comments
Closed

Issue with opaque struct across modules #3817

p0nce opened this issue Aug 17, 2021 · 8 comments

Comments

@p0nce
Copy link
Contributor

p0nce commented Aug 17, 2021

We stumble upon the following problem in dkorpel/libsoundio-d#3 (comment)

module a;

extern(C):

struct A;
void foo(A* a);
module b;

extern(C):

struct A {}
void foo(A* a) {}

When built:

$ ldc2 a.d b.d
a.d(6): Error: Function type does not match previously declared function with the same mangled name: `foo`
a.d(6):        Previous IR type: void (%b.A*)
a.d(6):        New IR type:      void (%a.A*)

But it works in DMD.

This doesn't create problem when module a and b are in different translation units, but typically will be exposed with dub --combined.

What to do?

@kinke
Copy link
Member

kinke commented Aug 17, 2021

This is yet another duplicate of #2782, #1020 etc. - hence closing. ;)

What to do?

If possible, extract the struct declaration to a separate module and import it from there. extern(C) doesn't change the fact that there are multiple unrelated struct types, and that there are conflicting foo() functions with different signatures.

@kinke kinke closed this as completed Aug 17, 2021
@dkorpel
Copy link
Contributor

dkorpel commented Aug 17, 2021

If possible, extract the struct declaration to a separate module and import it from there. extern(C) doesn't change the fact that there are multiple unrelated struct types, and that there are conflicting foo() functions with different signatures.

Does this mean DMD accepting this is a bug? The spec says that opaque structs can be used to implement the PIMPL idiom, but in LDC they're useless?

@kinke
Copy link
Member

kinke commented Aug 17, 2021

It boils down to that you cannot declare the same struct in multiple modules in D. So if the implementation of the struct is in another module, then no, the opaque struct and the impl don't refer to the same type.

@dkorpel
Copy link
Contributor

dkorpel commented Aug 17, 2021

Does LDC support another way of implementing the PIMPL idiom?

@kinke
Copy link
Member

kinke commented Aug 17, 2021

This has nothing to do with LDC per se, this is a general D restriction, it's just that DMD has much less strict codegen checks and according bugs, though one might argue that this extern(C[++]) function signatures check of LDC is overshooting at times and hindering some approaches. For a pimpl thing, I'd probably simply use a void* instead of A*.

@dkorpel
Copy link
Contributor

dkorpel commented Aug 17, 2021

I'll figure something out, thanks!

@kinke
Copy link
Member

kinke commented Aug 17, 2021

To make things clearer:

import a, b;

void main()
{
    A inst;
    foo(&inst);
}

=>

c.d(5): Error: struct `a.A` at a.d(5) conflicts with struct `b.A` at b.d(5)
c.d(5): Error: variable `c.main.inst` no definition of struct `A`

@p0nce
Copy link
Contributor Author

p0nce commented Aug 17, 2021

Does this mean DMD accepting this is a bug?

I think that yes, it's strange to accept it in the first place. the 2 struct have different fully qualified names.

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