extern(C) and mangling type names

Timothee Cour via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 14 20:51:43 PST 2017


looks like a dup of this:
http://forum.dlang.org/thread/mailman.445.1487070970.31550.digitalmars-d@puremagic.com
pragma(mangle,"name") for a type?




On Tue, Feb 14, 2017 at 7:40 PM, Mike Parker via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:

> ```
> module mang;
> extern(C):
>     struct Foo;
>     void bar();
>     int x;
>
> pragma(msg, Foo.mangleof);
> pragma(msg, bar.mangleof);
> pragma(msg, x.mangleof);
> ```
>
> 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.
>
> 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:
>
>
> ```
> module ec1;
> extern(C):
>     struct Foo;
>     Foo* newFoo(int x);
>     void printFoo(Foo* f);
>
> module ec2;
> extern(C):
>     struct Foo { int x; }
>     Foo* newFoo(int x) { return new Foo(x); }
>     void printFoo(Foo* f) { import std.stdio; writeln(f.x); }
>
> module ec3;
> void main() {
>     import ec1;
>     Foo* f = newFoo(30);
>     printFoo(f);
> }
> ```
>
> This compiles and runs. Now change ec1 and ec3 like so:
>
> ```
> module ec1;
> extern(C) struct Foo;
>
> module ec3;
> void main() {
>     import ec1, ec2;
>     Foo* f = newFoo(30);
>     printFoo(f);
> }
> ```
>
> This produces the following errors:
>
> ec3.d(4): Error: ec1.Foo at ec1.d(2) conflicts with ec2.Foo at ec2.d(3)
> ec3.d(4): Error: cannot implicitly convert expression (newFoo(30)) of type
> Foo* to Foo*
> ec3.d(5): Error: function ec2.printFoo (Foo* f) is not callable using
> argument types (Foo*)
>
> IMO, extern(C) should turn off mangling for Foo. It would make forward
> references useful outside of the specific case of C bindings.
>
> 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.
>
> 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.
>
> So, should extern(C) turn off mangling for types?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20170214/c37e9f81/attachment.html>


More information about the Digitalmars-d mailing list