โŒ About FreshRSS

Reading view

There are new articles available, click to refresh the page.

Unexpected Ada Type Compatibility

Why are Volts, Amps, and Ohms compatible?


with ada.text_io; use ada.text_io;
                                                                    
procedure main is                                                   
    type Volts is delta 1.0 / 2.0 ** 12 range -45_000.0 .. 45_000.0;
    type Amps is delta 1.0 / 2.0 ** 16 range -1_000.0 .. 1_000.0;   
    type Ohms is delta 0.125 range 0.0 .. 1.0E8;                    
                                                                    
    V : Volts := 1.0;                                               
    A : Amps := 1.0;                                                
    R1 : Ohms := 1.0;                                               
    R2 : Ohms := 1.0;                                               
                                                                   
begin                                             
                     
    v := A * (R1 + R2);
                       
    put_line(V'Img);   
                       
end main;  

If the types the types are defined as new Float I get the following exception during compilation:


main.adb:22:12: error: invalid operand types for operator "*"
main.adb:22:12: error: left operand has type "Amps" defined at line 5
main.adb:22:12: error: right operand has type "Ohms" defined at line 6

I expected the use of type with Volts to define a new type that was incompatible with the other types as it wasn't an explicit subtype of the fixed point type.

How to deallocate Ada Record from CPP

I am attempting to free a heap allocated Ada tagged record from cpp. I have used the code AdacoreU as a starting place.

I receive the following error when running the code below.

20
double free or corruption (out)

raised PROGRAM_ERROR : unhandled signal

Am I overthinking things? Do I need an Ada based deallocation mechanism.

What is my real end goal? I would like to use dynamic libraries to create a plugin infrastructure where each library is its own factory for a given type. Something along the lines of boost dll but with ada based dynamic libraries.

Modified Code below:

main.cpp

  1 #include <iostream>
  2 #include "animal.h"
  3 
  4 extern "C" {
  5     void adainit (void);
  6     void adafinal (void);
  7     Animal* new_animal();
  8     void del_animal(Animal *);
  9 }
 10 
 11 int main(void) {
 12     adainit();
 13     Animal* A = new_animal();
 14     std::cout << A->age() << std::endl;
 15     //delete A;   
 16     del_animal(A);
 17     adafinal();
 18     return 0;
 19 };

alib.ads

  1 
  2 with Interfaces.C;
  3 
  4 package ALib is
  5 
  6     type Animal is tagged record
  7         The_Age : Interfaces.C.int;
  8     end record;
  9     pragma Convention (CPP, Animal);
 10 
 11     type Animal_Class_Access is access Animal'Class;
 12 
 13     function New_Animal return access Animal'Class;
 14     pragma Export(CPP, New_Animal);
 15 
 16     procedure Del_Animal (this : in out Animal_Class_Access);
 17     pragma Export(CPP, Del_Animal);
 18 
 19     function Age(X : Animal) return Interfaces.C.int;
 20     pragma Export(CPP, Age);
 21 
 22 end ALib;

alib.adb

  1 with ada.unchecked_deallocation;
  2 
  3 package body ALib is
  4 
  5     function New_Animal
  6         return access Animal'Class is
  7     begin
  8         return new Animal'(The_Age => 20);
  9     end New_Animal;
 10 
 11 
 12     procedure Del_Animal (this : in out Animal_Class_Access) is
 13         procedure Free is new ada.unchecked_deallocation(Animal'Class, Animal_Class_Access);
 14     begin
 15         Free(this);
 16         --null;
 17     end Del_Animal;
 18 
 19     function Age(X : Animal)
 20         return Interfaces.C.int is
 21     begin
 22         return X.The_Age;
 23     end Age;
 24 
 25 end ALib;
~              

other resources used as a starting point

3.11.3.5 Interfacing with C++ at the Class Level

What have I attempted:

  • Used various combinations of the type and access type when attempting to create the Free procedure
    • Animal, type Animal_Access is access Animal
    • Animal'Class, type Animal_Class_Access is access Animal'Class
    • Animal, type Animal_Access is access Animal'Class
  • I was at some point under the impression that I should be using system address for the pointers to the Animal object as either part of the return on New_Animal and as the argument to Del_Animal

What did I expect:

I expected to clean up Ada heap objects from Ada.

โŒ