Wrong C++ constructor called for abstract class
//////////////// testabstractcpp.cpp ////////////////
class C
{
public:
C();
virtual void f() = 0;
int i;
};
C::C()
{
i = 5;
}
////////////////// testabstractd.d //////////////////
extern(C++) abstract class C
{
this();
abstract void f();
int i;
}
extern(C++) class D : C
{
override void f()
{
assert(i == 5);
}
}
void main()
{
D d = new D();
d.f();
}
/////////////////////////////////////////////////////
The files can be compiled with the following commands:
clang++ -c testabstractcpp.cpp
dmd -L-lstdc++ testabstractd.d testabstractcpp.o
The second command results in a linker error:
/usr/bin/ld: testabstractd.o:(.data._D13testabstractd1C7__ClassZ+0x88): undefined reference to `C::C()'
/usr/bin/ld: testabstractd.o: in function `D::D()':
testabstractd.d:(.text._ZN1DC1Ev[_ZN1DC1Ev]+0x14): undefined reference to `C::C()'
The Itanium C++ ABI has different constructors. Clang seems to only emit the base object constructor (_ZN1CC2Ev) for abstract class C, but dmd tries to use the complete object constructor (_ZN1DC1Ev).
The example work with GCC, because it emits both constructors.
Comment #1 by robert.schadek — 2024-12-13T19:20:10Z