<div dir="ltr">looks like a dup of this:<div><a href="http://forum.dlang.org/thread/mailman.445.1487070970.31550.digitalmars-d@puremagic.com">http://forum.dlang.org/thread/mailman.445.1487070970.31550.digitalmars-d@puremagic.com</a> pragma(mangle,"name") for a type?<br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 14, 2017 at 7:40 PM, Mike Parker via Digitalmars-d <span dir="ltr"><<a href="mailto:digitalmars-d@puremagic.com" target="_blank">digitalmars-d@puremagic.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">```<br>
module mang;<br>
extern(C):<br>
    struct Foo;<br>
    void bar();<br>
    int x;<br>
<br>
pragma(msg, Foo.mangleof);<br>
pragma(msg, bar.mangleof);<br>
pragma(msg, x.mangleof);<br>
```<br>
<br>
Obviously, x and bar are seen by the linker and mangling is turned off for them. I've always believed it was the same for type declarations as well. Alas, that is not the case.<br>
<br>
The use case I'm looking at here is forward references (opaque types). Works fine when binding to C libraries. Or even with other D modules when written like this:<br>
<br>
<br>
```<br>
module ec1;<br>
extern(C):<br>
    struct Foo;<br>
    Foo* newFoo(int x);<br>
    void printFoo(Foo* f);<br>
<br>
module ec2;<br>
extern(C):<br>
    struct Foo { int x; }<br>
    Foo* newFoo(int x) { return new Foo(x); }<br>
    void printFoo(Foo* f) { import std.stdio; writeln(f.x); }<br>
<br>
module ec3;<br>
void main() {<br>
    import ec1;<br>
    Foo* f = newFoo(30);<br>
    printFoo(f);<br>
}<br>
```<br>
<br>
This compiles and runs. Now change ec1 and ec3 like so:<br>
<br>
```<br>
module ec1;<br>
extern(C) struct Foo;<br>
<br>
module ec3;<br>
void main() {<br>
    import ec1, ec2;<br>
    Foo* f = newFoo(30);<br>
    printFoo(f);<br>
}<br>
```<br>
<br>
This produces the following errors:<br>
<br>
ec3.d(4): Error: ec1.Foo at ec1.d(2) conflicts with ec2.Foo at ec2.d(3)<br>
ec3.d(4): Error: cannot implicitly convert expression (newFoo(30)) of type Foo* to Foo*<br>
ec3.d(5): Error: function ec2.printFoo (Foo* f) is not callable using argument types (Foo*)<br>
<br>
IMO, extern(C) should turn off mangling for Foo. It would make forward references useful outside of the specific case of C bindings.<br>
<br>
Consider the situation where you want to call a user-defined function (not a function pointer or a delegate). It's easy to do by providing an extern(C) prototype and requiring the user to use extern(C) in the implementation. The same thing should be possible for types.<br>
<br>
My specific use case is a binding to a C library that makes use of specific types from X11, Wayland and elsewhere. I don't want to force a specific binding upon the user, so I need to declare the relevant types in a way that is binding-neutral. One option, of course, is to use void*, which has a lack of type safety and requires casting all over the place. Another is to wrap the declarations up in mixin templates and have the user mix them where they've imported the specific binding. Less onerous than void*, but still not ideal.<br>
<br>
So, should extern(C) turn off mangling for types?<br>
</blockquote></div><br></div>