Ada interfacing C++: instance destroyed

I want to use a C++ library that implements the Factory Method design pattern.

Below you can see a minimal reproducibable example, including C++ sources and the Ada adapter.

  • Item.h:

    // Product interface
    #ifndef _ITEM_H_
    #define _ITEM_H_
    class Item {
      virtual ~Item() = default;
      virtual void do_something() = 0;
  • ConcreteItem.h:

    #ifndef _CONCRETEITEM_H_
    #define _CONCRETEITEM_H_
    #include "Item.h"
    class ConcreteItem : public Item {
      void do_something();
  • ConcreteItem.cpp:

    #include <stdlib.h>
    #include <iostream>
    #include "ConcreteItem.h"
    void ConcreteItem::do_something() {
      std::cout << "Doing stuff \n";
    ConcreteItem::ConcreteItem() {
      std::cout << "Concrete Item created \n";
      std::cout << "Concrete Item destroyed \n";
  • Factory.h:

    #ifndef _FACTORY_H_
    #define _FACTORY_H_
    #include "Item.h"
    class Factory {
      static Item* get_configured_item ();
      Factory(Factory& other) = delete;
      static Factory* factory;
      static Item* config_item;
  • Factory.cpp:

    #include "Factory.h"
    #include "ConcreteItem.h"
    Factory* Factory::factory = nullptr;
    Item* Factory::config_item = nullptr;
    Item *Factory::get_configured_item() {
      if (Factory::factory == nullptr) {
        Factory::factory = new Factory();
        if (Factory::config_item == nullptr) {
          Factory::config_item = new ConcreteItem();
      return Factory::config_item;
    Factory::~Factory() {
      delete Factory::config_item;

And here I have the Ada files that imports C++ symbols, generated with a call to g++ -c -fdump-ada-spec -C ./Factory.h and doing some modifications to suite my taste:

  • Factory_h.ads:
    limited with Item_h;
    package Factory_h is
      type Factory is limited record
      end record
        with Import => True,
        Convention => CPP;
      function get_configured_item return access Item_h.Item'Class  -- ./Factory.h:9
        with Import => True, 
        Convention => CPP, 
        External_Name => "_ZN7Factory19get_configured_itemEv";
    end Factory_h;
  • Item_h.ads:
    with Interfaces.C;
    package Item_h is
      type Item is limited interface
        with Import => True,
        Convention => CPP;
      --  procedure Delete_Item (this : access Item) is abstract;-- ./Item.h:8
      --  procedure Delete_And_Free_Item (this : access Item) is abstract; -- ./Item.h:8;
      procedure do_something (this : access Item) is abstract;  -- ./Item.h:9
    end Item_h;

And finaly an Ada main to test this silly example:

with Factory_h;
with Item_h;

procedure main is
  configured_item : constant access Item_h.Item'Class :=

end main;

Do you know why if I comment out the Item primitives Delete_Item and Delete_And_Free_Item the call to do_something is never done and the item is destroyed?

If I uncomment them everything works.

Thanks in advance!


  • I'm far from expert on Ada-C++ interfacing, but my guess is that in the C++ code, do_something is the third entry in the virtual-function table for ConcreteItem. The dump-ada-spec operation adds Delete_Item and Delete_And_Free_Item to occupy the first two slots in the v-table on the Ada side, which makes do_something the third entry in the v-table, matching its position on the C++ side.

    When you comment out Delete_Item and Delete_And_Free_Item this makes do_something be the first entry in the v-table on the Ada side. So when Ada calls do_something, it actually calls the first v-table entry, which on the C++ side is some other function -- apparently one that performs Delete_Item.