Bug 21903 – Class construction for C++ interop with -betterC

Status
RESOLVED
Resolution
WORKSFORME
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-05-07T16:09:17Z
Last change time
2023-04-10T10:08:17Z
Keywords
betterC, C++
Assigned to
No Owner
Creator
SHOO

Comments

Comment #0 by zan77137 — 2021-05-07T16:09:17Z
If you are using betterC and want to interoperate with C++, you may want to construct instances of your classes in D language code. In betterC, it should not be possible to use new to do memory allocation in GC, but it should be possible to use `emplace` to do the construction. Specifically, I think the following code may work: ------------------------------------- import core.lifetime: emplace; import core.stdc.stdio: printf; extern(C++) class A { int a = 5; int foo() { return a; }; } extern(C++) class B: A { int b = 10; override int foo() { return a + b; }; } extern(C) void main() { ubyte[__traits(classInstanceSize, B)] buf; auto b = emplace!B(buf[]); printf("%d\n", b.foo()); } ------------------------------------- dmd -betterC -run main.d ------------------------------------- https://run.dlang.io/is/QNGYvL However, this does not work in fact. This is because `emplace` internally copies memory from typeid(T).initializer and depends on TypeInfo. To achieve this, you will need to do one of the following - Provide a way to get the default initializer value of a member variable. ex) `__traits(getDefaultInitializerValue, T.a)` - Make typeid(T).initializer available at compile time. ex) `static immutable buf = typeid(T).initializer;` - Provide a way to get a buffer equivalent to typeid(T).initializer. ex) `static immutable buf = __traits(getInitializerBuffer, T)`
Comment #1 by destructionator — 2021-05-07T16:13:34Z
Try scope B b = new B(); it should work.
Comment #2 by zan77137 — 2021-05-07T16:28:31Z
(In reply to Adam D. Ruppe from comment #1) > Try > > scope B b = new B(); > > it should work. This method is not flexible enough for compound use of custom allocators, templates, and classes without default constructors.
Comment #3 by kinke — 2021-11-08T13:53:52Z
This works with LDC v1.27+ due to `__traits(initSymbol, T)` [with an additional `-release` to circumvent a check for matching buffer length requiring druntime].
Comment #4 by razvan.nitu1305 — 2023-04-10T10:08:17Z
Works with dmd also.