On 2016-07-15 19:52, cy wrote:
I would never (ever) do this myself, but trying to understand dmd, the
code is absolutely packed with things like this:
extern(C++) class Package : ScopeDSymbol
{
...
override const(char)* kind() const
{
return "package";
}
...
override final inout(Package) isPackage() inout
{
return this;
}
...etc...
}
How exactly does that... work? Is the body of such a member function
written in the D Programming Language?
Yes. Just as it's possible to call C function from D, it's possible to
implement functions in D that can be called from C. This compatibility
applies C++ and Objective-C as well.
When the D compiler sees a "extern(C++)" declaration it will adopt the
code and output the data structures to be compatible with C++. For
example, the location of the vtable, name mangling and so on.
The documents say nothing about this, only defining their examples as
stubs, like
extern(C++) class Foo {
void bar();
}
The documentation also avoids any memory allocation in D, instead
assuming C++ routines like createInstance to use malloc to allocate the
classes. But the code in dmd makes extensive use of things like this:
extern(C++) ... {
final extern(D) this(...) { ... }
}
IIRC, it's not possible to call a C++ constructor from D. That's why
"extern(D) this" is used to be able to do the memory allocation from the
D side.
How would you create new objects of types that are declared extern(C++)?
Just new, and mark the constructor as extern(D)?
I realize DMD is a horrible program that was Frankensteined from C++
code ages ago and is practically still C++ itself
The front end was only fairly recently converted to D.
--
/Jacob Carlborg