Normal view

There are new articles available, click to refresh the page.
Before yesterdayNewest questions tagged ada - Stack Overflow

Difference between statements inside and outside accept block

Suppose the following (server) task specification:

task type Server_Task is
      entry E1(I: Integer);
      entry E2;
      entry E3;
end Server_Task;

with a (dummy) implementation of:

task body Server_Task is      
   begin
      loop
         select
            accept E1(I: Integer) do
               -- statements inside E1 using I
               -- statements inside E1 using I
               -- statements inside E1 using I
               null;
            end;                       
         or
            accept E2 do
               null;               
            end;
         or
            accept E3 do
               null;
            end; 
         end select;         
      end loop;     
end Server_Task;

Based on my understanding, if a client task makes an entry call for (say) E1 then all statements inside the E1 accept block will be executed before the server task loops over again and is ready to accept another entry call. The same is true if there are further statements following the end of the accept block so that again all these will need to run before the task can randevouz with a calling task again. If that assumption is correct, I'm wondering what the behavioural difference is between the above implementation and the one below:

task body Server_Task is
      Temp: Integer;
   begin
      loop
         select
            accept E1(I: Integer) do
               Temp := I;       
            end;
            -- statements outside E1 using Temp
            -- statements outside E1 using Temp
            -- statements outside E1 using Temp
         or
            accept E2 do
               null;               
            end;
         or
            accept E3 do
               null;
            end; 
         end select;         
      end loop;     
end Server_Task;

Will there be a difference if the statements outside E1 make a blocking call and hence the server task is suspended and therefore these statements will then have to somehow compete with any other entry calls made by the task's clients? (though this doesn't make much sense if the task is implemented using just one "thread"?)

For the sake of argument suppose the client code is along the lines of:

ST: Server_Task;   
   task body Client_Task is
   begin
      select
         ST.E2;
      else
         -- do something else
         null;
      end select;
      null;
   end Client_Task;

Is this behaviour detailed somewhere in the ARM? - Thanks

Unable to link C source code with Ada static library (Error: libnewapi.a(unit1.o):unit1.adb:undefined reference to `__gnat_rcheck_CE_Overflow_Check')

I want to integrate my Ada static library (libnewapi.a) with my C source code (main.c). I do not have any issues generating the static library but when trying to link it with main.c. I get the below link error, libnewapi.a(unit1.o):unit1.adb:(.text+0x31): undefined reference to `__gnat_rcheck_CE_Overflow_Check' I am not using this reference in my main.c not in any of my Ada files. I do not know why this reference was added automatically. It is crucial that I need to link my main.c using a static Ada library for my project. I do not know where I am going wrong. Help is much appreciated. Thanks!

I am generating libnewapi.a using a GPR as below,

    -- ada_gen_a.gpr
    project ada_gen_a is
       for Languages use ("Ada");
       for Source_Dirs use ("./");
       for Library_Name use "newapi";
       for Library_Dir use "./Lib/";
       for Library_Kind use "static";

       package Naming is
          for Spec_Suffix ("ada") use ".ads";
          for Body_Suffix ("ada") use ".adb";
          for Separate_Suffix use ".adb";
          for Dot_Replacement use ".";
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;
    end ada_gen_a;

Ada Sourcefiles:

    --  unit1.ads
    package Unit1 is
       function Add (A, B : Integer) return Integer;
       pragma Export (C, Add, "ada_add");
    end Unit1;
    -- unit1.adb
    package body Unit1 is
       function Add (A, B : Integer) return Integer is
       begin
          return A + B;
       end Add;
    end Unit1;

C Source File:

    /* main.c */
    #include <stdio.h>
    extern void ada_add (void);
    int main (int argc, char *argv[])
    {
       int a = 21, b = 7, c = 0;
       printf ("%d", a);
       printf ("%d", b);
       c = ada_add(a,b);
       printf ("%d", c);
       return 0;
    }

I am using the below GPR to link the above main.c with the Ada static library generated using ada_gen_a.gpr.

    -- Ada_Use_A.gpr
    with "newapi.gpr";
    project Ada_Use_A is

       for Languages use ("C");
       for Source_Dirs use (".");
       for Source_Files use ("main.c");

       package Naming is
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("C") use ("-O2", "-Wall");
          for Default_Switches ("Ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;

       for Main use ("main.c");

    end Ada_Use_A;
    -- newapi.gpr
    project newapi is
       for Externally_Built use "true";
       for Source_Files use ();
       for Library_Dir use ".\lib\";
       for Library_Name use "newapi";
       for Library_Kind use "static";
    end newapi;

When I try to build the Ada_Use_A.gpr GPS I get the below linker error, libnewapi.a(unit1.o):unit1.adb:(.text+0x31): undefined reference to __gnat_rcheck_CE_Overflow_Check' gprbuild: link of main.c failed`

gdb on MacOS Ventura fails with python library not loaded

I have a build of gdb for an Ada toolchain, and it appears there is a reference to a Python dynamic library that does not exist on my system (Intel Mac, Ventura 13.4.1 (c)).

$ which gdb
/opt/gcc-13.1.0/bin/gdb

$ gdb
dyld[19305]: Library not loaded: /Library/Frameworks/Python.framework/Versions/3.9/Python
  Referenced from: <3FCB836C-8BBC-39C7-894C-6F9582FEAE7F> /opt/gcc-13.1.0/bin/gdb
  Reason: tried: '/Library/Frameworks/Python.framework/Versions/3.9/Python' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Library/Frameworks/Python.framework/Versions/3.9/Python' (no such file), '/Library/Frameworks/Python.framework/Versions/3.9/Python' (no such file), '/System/Library/Frameworks/Python.framework/Versions/3.9/Python' (no such file, not in dyld cache)
Abort trap: 6

$ dyld_info /opt/gcc-13.1.0/bin/gdb
/opt/gcc-13.1.0/bin/gdb [x86_64]:
    -platform:
        platform     minOS      sdk
           macOS     12.0      10.17  
    -segments:
        load-offset   segment section        sect-size  seg-size perm
        0x00000000    __TEXT                              7728KB r.x
        0x00001090             __text           5025114
        0x004CBDF0             __text_startup    23672
        0x004D1A68             __text_cold      125143
        0x004F0340             __stubs            9060
        0x004F26A4             __stub_helper      6276
        0x004F3F28             __cstring        899918
        0x005CFA80             __const          155833
        0x005F5B40             __info_plist        466
        0x005F5D18             __eh_frame       1663704
        0x0078C000    __DATA_CONST                        1088KB rw.
        0x0078C000             __got              5824
        0x0078D6C0             __mod_init_func     800
        0x0078D9E0             __const          1099176
        0x0089C000    __DATA                               304KB rw.
        0x0089C000             __la_symbol_ptr   12080
        0x0089EF30             __gcc_except_tab 118952
        0x008BBFE0             __data            76000
        0x008CE8C0             __bss             91000
        0x008E4C40             __common           9104
    -dependents:
        attributes     load path
                       /usr/lib/libiconv.2.dylib
                       /usr/lib/libncurses.5.4.dylib
                       /Library/Frameworks/Python.framework/Versions/3.9/Python
                       /usr/lib/libexpat.1.dylib
                       /opt/gcc-13.1.0/lib/libmpfr.6.dylib
                       /opt/gcc-13.1.0/lib/libgmp.10.dylib
                       /opt/gcc-13.1.0/lib/libstdc++.6.dylib
                       /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
                       /usr/lib/libSystem.B.dylib

$ ls /Library/Frameworks/Python.framework
ls: /Library/Frameworks/Python.framework: No such file or directory

$ which python3
/usr/bin/python3

$ which python3.9
/usr/local/bin/python3.9

I have installed Python via brew. Where should I look for the required library (so I can set DYLD_LIBRARY_PATH), or how can I install the proper one?

Build static library from Ada code to be linked without GNAT

I'm trying to create a static library from Ada code that can be linked with some C code without using GNAT tools for the final linking. My use case is that I'm trying to deliver a library written in Ada towards a codebase in C that will be built for an embedded target. The toolchain to build the final binary for the target does not contain GNAT tools and hence the requirement to be able to link the library without GNAT.

When I try to link the library, I get a lot of errors about undefined references.

Here is a minimal code example. C_Ada_Cross.gpr file:

project C_Ada_cross is
   for Library_Name use "MathFunc";
   for Source_Dirs use ("src", ".");
   for Object_Dir use "obj";
   for Library_Kind use "static";
   for Library_Interface use ("MathFunc_Ada");
   for Library_Src_Dir use "include";
   for Library_Dir use "lib";
end C_Ada_cross;

MathFunc_Ada.ads file:

with Interfaces.C; use Interfaces.C;

function MathFunc_Ada(a: C_Float; b: C_Float) return C_Float
    with 
        Export      => True,
        Convention  => C,
        External_Name => "MathFunc_Ada";

MathFunc_Ada.adb file:

with Ada.Numerics.Elementary_Functions; 
function MathFunc_Ada(a: C_Float; b: C_Float) return C_Float is
    use Ada.Numerics.Elementary_Functions;
begin
    return C_Float(sin(Float(a)) + cos(Float(b)));
end MathFunc_Ada;

main.c file:

#include <stdio.h>

extern float MathFunc_Ada(float a, float b);
extern void MathFuncinit();
extern void MathFuncfinal();

void main() {
  MathFuncinit();

  float a = 10.2;
  float b = 20.6;
  float c = MathFunc_Ada(a, b);
  
  printf("%f\n", c);
  MathFuncfinal();
}

To build, I did the following:

gprbuild -P C_Ada_cross.gpr # libMathFunc.a 
gcc main.c -L./lib -lMathFunc

And this generates loads of errors like so:

/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libMathFunc.a(p__MathFunc_0.o):MathFunc_Ada.a:(.text+0x20): undefined reference to `ada__numerics__elementary_functions__sin'
./lib/libMathFunc.a(p__MathFunc_0.o):MathFunc_Ada.a:(.text+0x20): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `ada__numerics__elementary_functions__sin'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libMathFunc.a(p__MathFunc_0.o):MathFunc_Ada.a:(.text+0x2f): undefined reference to `ada__numerics__elementary_functions__cos'
./lib/libMathFunc.a(p__MathFunc_0.o):MathFunc_Ada.a:(.text+0x2f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `ada__numerics__elementary_functions__cos'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x118): undefined reference to `system__secondary_stack__ss_stackIP'
./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x118): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `system__secondary_stack__ss_stackIP'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x14e): undefined reference to `__gnat_runtime_finalize'
./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x14e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__gnat_runtime_finalize'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x265): undefined reference to `__gnat_runtime_initialize'
./lib/libMathFunc.a(p__MathFunc_0.o):b__mathfunc.ad:(.text+0x265): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__gnat_runtime_initialize'

and more...

I also tried:

gcc main.c -L./lib -lMathFunc -lgnat -lgnarl -ldl

and that gives different undefined reference errors:

/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: DWARF error: can't find .debug_ranges section.
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x38): undefined reference to `__imp__wsplitpath'
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x38): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__imp__wsplitpath'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libgnat.a(adaint.o):adaint.c:(.text+0x480): undefined reference to `__mingw_vsprintf'
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x480): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__mingw_vsprintf'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4d5): undefined reference to `__imp__time64'
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4d5): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__imp__time64'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4ec): undefined reference to `__imp__time64'
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4ec): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__imp__time64'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4fc): undefined reference to `__imp__localtime64'
./lib/libgnat.a(adaint.o):adaint.c:(.text+0x4fc): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__imp__localtime64'
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: ./lib/libgnat.a(adaint.o):adaint.c:(.text+0x54f): undefined reference to `__imp__gmtime64'

and more...

The last approach is very similar to the one presented here: https://stackoverflow.com/a/70036096/3979564, but that didn't work for me. In fact, I even tried the exact same code and commands presented there, but that gave me similar errors.

I found this option when searching for solutions: http://www.white-elephant.ch/articles/AUJ%2042-3.pdf, but that seems very convoluted to make a copy of and rewrite original Ada source files.

Given Ada's focus on embedded applications where static linking is the only option in many cases, I feel like there must be a simpler way to build static libraries.

Am I missing something? Is there an easier way to build static libraries in Ada?

Define address depending on target

I have a gpr project with 2 targets :

mySources  := "My project files"
case Rules.Target is
    when "CASE1" =>
         mySources := "File1" & mySources 
    when "CASE2" =>
         mySources := "File2"  & mySources 
    when others =>
end case
for Source_Dirs use mySources 

I have File1 containing the variable local_Address :

local_Address : constant System.Address := Function_to_get_Address();

On a commonFile I want to do :

-- Type definition
type My_Array_Type is array (Boolean) of My_Type;

-- Variable definition
My_Array : My_Array_Type;
for My_Array'Address use local_Address; --only for CASE1

How can I write my file2 to have default address ? Or maybe I have to redefine my software design ?

Edit:

In CASE2 I don't want to specify any address.

Ada Program That Asks For Name And Echoes It Back Errors Won't Compile

I'm learning Ada, and I am trying to write a program that asks for the user's name, and then echoes it back. But it gives me a few errors and refuses to compile. One of the many errors is too many calls to get_line. I'm using macOS Ventura M1 GCC 13.1.0 Gnat Studio. I get the same types of errors with Visual Studio Code, the same program will freeze and then you have to manually stop the program inside VSC. I can write a calculator, and "Hello, World!" this simple program is not working.

I tried the same code in Gnat Studio and Visual Studio Code. The program should prompt the user for their first name, and the program should say: "Hello, !"

Compile error when implementing interface

I am experimenting a bit (out of academic interest, no tangible use-case) with protected interfaces and have come-up with the following code:

procedure Protected_Map is
   type Key is new Character range 'A' .. 'K';
   type Value is range -10 .. 10;
   
   package Maps is
      type Map is protected interface;
      procedure Insert(M: out Map; K: in Key; V: in Value) is abstract;
      procedure Find(M: in out Map; K: in Key; V: out Value) is abstract;
   end Maps;
   use Maps;
   
   -- protected type implementation
   protected type A_Map is new Map with
      overriding
      procedure Insert(K: in Key; V: in Value);
      not overriding
      function Get(K: in Key) return Value;       
   end A_Map;
   
   protected body A_Map is
      procedure Insert(K: in Key; V: in Value) is null; -- dummy
      function Get(K: in Key) return Value is (0); -- dummy
   end A_Map;
   
   overriding
   procedure Find(M: in out A_Map; K: in Key; V: out Value) is
   begin
      V:= M.Get(K);
   end Find;
begin
   null;
end Protected_Map;

The idea is to implement a task-safe Map by declaring a protected interface type with the associated procedures of inserting and finding values by some key. A protected type is then declared in order to implement the interface which only partly implements it (i.e. Insert(..)) and introduces a Get(..) function to retrieve a value by some key. The second required procedure (Find(..)) is implemented in an independent full-blown way. The reason for this is so that writers continue to access the map in a mutually exclusive way whilst readers are able to access it concurrently.

However, compilation is failing for Find(..) with the compiler complaining that no selector "Get" for type derived from A_Map. Why can it not see Get which is clearly in the protected type declaration? Is it a scoping issue i.e. do the protected type declaration and the independent implementation need to be in the same package? (or some other unit?)

Ada2012: possible error for Ada.Finalization.Limited_Controlled?

I'm facing now the following weird run-time error:

raised PROGRAM_ERROR : s-finroo.adb:42 explicit raise

I'm trying to implement an Observer design pattern. Since my observers are limited and I want to avoid general access types, I'm storing the observers' address and notifying them using Ada.Adress_To_Access_Conversions. My concrete observers are inheriting from Ada.Finalization.Limited_Controlled as I have to initialize and finalize them somehow as per my implementation. Take a look at components.ads below, where Component_t is defined.

I leave you a minimal reproducibable example:

eventpublisher.ads

private with System;

package eventPublisher is

  type Observer_t is limited interface;
  procedure Event (this : in out Observer_t) is abstract;

  type EventPublisher_t is tagged limited private;
  procedure pSubscribeEvent (this : in out EventPublisher_t;
                             TrainId : Natural;
                             sub : Observer_t'Class);

  procedure pUnsubscribeEvent (this : in out EventPublisher_t;
                               TrainId : Natural;
                               sub : Observer_t'Class);

  procedure pNotifyEvent (this : in out EventPublisher_t);

  function fGetEventPublisher return not null access EventPublisher_t;

private

  type EventObserver_t is tagged
     record
       obs : System.Address := System.Null_Address;
     end record;

  type EventPublisher_t is tagged limited
     record
       eventManager : EventObserver_t;
     end record;

end eventPublisher;

eventpublisher.adb

with System.Address_To_Access_Conversions;
with Ada.Text_IO;

package body eventPublisher is

  function "=" (Left, Righ : System.Address) return Boolean renames System."=";

  eventPublisher : access EventPublisher_t := new EventPublisher_t;

  package Event_OPS is new System.Address_To_Access_Conversions (Observer_t'Class);

  function fGetEventPublisher return not null access EventPublisher_t is
  begin
    return eventPublisher;
  end fGetEventPublisher;

  -------------------
  -- pSubscribeEvent --
  -------------------

  procedure pSubscribeEvent
    (this : in out EventPublisher_t; TrainId : Natural;
     sub  :        Observer_t'Class)
  is
  begin
    Ada.Text_IO.Put_Line("Subscribing to Event");
    this.eventManager.obs := sub'Address;
  end pSubscribeEvent;

  procedure pUnsubscribeEvent (this : in out EventPublisher_t;
                               TrainId : Natural;
                               sub : Observer_t'Class) is
  begin
    Ada.Text_IO.Put_Line("Unsubscribing to Event");
    if this.eventManager.obs = sub'Address then
      this.eventManager.obs := System.Null_Address;
    else
      null;
    end if;

  end pUnsubscribeEvent;

  procedure pNotifyEvent (this : in out EventPublisher_t) is
  begin
    if this.eventManager.obs /= System.Null_Address then
      Ada.Text_IO.Put_Line("Notifying to observer");
      Event_OPS.To_Pointer(this.eventManager.obs).Event;
    end if;
  end pNotifyEvent;

components.ads

with eventPublisher;
private with Ada.Finalization;

package components is

  type Root_t (Id : Natural) is abstract tagged limited null record;

  type Child_t (Id : Natural) is limited new Root_t with private;

  procedure pSubscribe (this : in out Child_t);
  procedure pUnsubscribe (this : in out Child_t);

private

  type Component_t (Id : Natural) is limited new
    Ada.Finalization.Limited_Controlled and --> if you comment out this, everything works
    eventPublisher.Observer_t with null record;

  overriding
  procedure Event (this : in out Component_t);

  type Child_t (Id : Natural) is limited new Root_t (Id => Id) with
     record
       component : Component_t(Id => Id);
     end record;

end components;

components.adb

with Ada.Text_IO;

package body components is
  -----------
  -- Event --
  -----------

  overriding procedure Event (this : in out Component_t) is
  begin
    Ada.Text_IO.Put_Line("Processing Event");
  end Event;
  ----------------
  -- pSubscribe --
  ----------------

  procedure pSubscribe (this : in out Child_t) is
  begin
    eventPublisher.fGetEventPublisher.pSubscribeEvent(TrainId => this.Id,
                                                    sub => this.component);
  end pSubscribe;

  procedure pUnsubscribe (this : in out Child_t) is
  begin
    eventPublisher.fGetEventPublisher.pUnsubscribeEvent(TrainId => this.Id,
                                                      sub => this.component);
  end pUnsubscribe;

end components;

And finally, main.adb

with Ada.Text_IO;
with components;
with eventPublisher;

procedure Main is

  c : components.Child_t(Id => 1);
  pub : constant access eventPublisher.EventPublisher_t := eventPublisher.fGetEventPublisher;

begin
  c.pSubscribe;
  pub.pNotifyEvent;
  c.pUnsubscribe;
end Main;

This is the backtrace:

#0  <__gnat_debug_raise_exception> (e=0x45ab60 <program_error>, message=...) at s-excdeb.adb:41
#1  0x0000000000407265 in ada.exceptions.complete_occurrence (x=x@entry=0x467300) at a-except.adb:1019
#2  0x0000000000407275 in ada.exceptions.complete_and_propagate_occurrence (x=x@entry=0x467300) at a-except.adb:1030
#3  0x00000000004076ac in ada.exceptions.raise_with_location_and_msg (e=0x45ab60 <program_error>, f=(system.address) 0x4437d8, l=42, c=c@entry=0, m=m@entry=(system.address) 0x441150) at a-except.adb:1241
#4  0x0000000000407629 in <__gnat_raise_program_error_msg> (file=<optimized out>, line=<optimized out>, msg=msg@entry=0x441150 <ada.exceptions.rmsg_22>) at a-except.adb:1197
#5  0x00000000004078e0 in <__gnat_rcheck_PE_Explicit_Raise> (file=<optimized out>, line=<optimized out>) at a-except.adb:1435
#6  0x0000000000416ba5 in system.finalization_root.adjust ()
#7  0x0000000000404fea in eventpublisher.pnotifyevent ()
#8  0x00000000004041be in main ()

Do you know what the heck is going on? Why the run-time is calling to Adjust for a Limited_Controlled type at trace #6?

Why and how to fix this error message using Ada?

with Ada.Text_IO ; use Ada.Text_IO ;
with Ada.Float_Text_IO ; use Ada.Float_Text_IO ;
with Ada.Integer_Text_IO ; use Ada.Integer_Text_IO ;

procedure Main is

begin

   declare
      V_PRODUCT := Float;
      V_RETURN := Float;
      V_PAID := Floar;
      
      type V_COIN is delta 0.01 digist 8;
      type INDEX is range 1 ..8;
      
      type MY_RANGE_COIN is array (INDEX) of V_COIN;
      Arr: MY_RANGE_COIN := (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0);
      
      
      --T_COINS
      
   begin
      Put_Line ("Introducir precio del prodcuto. ");
      Get (V_PRODUCT);
      
      Put_Line ("Introducir cuantia");
      Get (V_PAID);
      
      Put_Line ("La cantidad a devolver es : " & V_RETURN);
  
   end;
   
   function V_RETURN;
   declare
      REFUND : Float := 0.0;
   begin
      REFUND := V_PAID - V_PRODUCT;
      return REFUND ;
   end;
   
   
   null;
end Main;

That is the error. enter image description here

I'm trying to make a machine that returns the return of a purchase.

V_PRODUCT --> Value_PRODUCT
V_RETURN --> Value_RETURN
V_PAID --> Value_PAID

All of this -->

type V_COIN is delta 0.01 digist 8;
      type INDEX is range 1 ..8;
      type MY_RANGE_COIN is array (INDEX) of V_COIN;
      Arr: MY_RANGE_COIN := (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0);

Its for made array with all Euro coin value.

Funtion it's just for know how many need to return.

Ada2012: inherited discriminant not allowed here

I have the following problem and I don't really understand why:

procedure Main is
  
  type Component_t (Id : Natural) is tagged limited null record;
  
  type Root_t (Id : Natural) is tagged limited null record;
  
  type Child_t is limited new Root_t with
     record
       component : Component_t(Id => Id);
     end record;

begin
   --  Insert code here.
   null;
end Main;

9:38 -> error: Id is not visible

error: non-visible declaration at line 5

error: inherited discriminant not allowed here (RM 3.8 (12), 3.8.1 (6))

I'm not sure if the mentioned RM's are the following:

3.8 12/3 A name that denotes a noninherited discriminant is allowed within the declaration of the type, but not within the discriminant_part. If the discriminant is used to define the constraint of a component, the bounds of an entry family, or the constraint of the parent subtype in a derived_type_definition, then its name shall appear alone as a direct_name (not as part of a larger expression or expanded name). A discriminant shall not be used to define the constraint of a scalar component.

3.8.1 6 The discriminant_direct_name shall resolve to denote a discriminant (called the discriminant of the variant_part) specified in the known_discriminant_part of the full_type_declaration that contains the variant_part. The expected type for each discrete_choice in a variant is the type of the discriminant of the variant_part.

If I declare child_t as follows it compiles, but it seems really weird to me. Is it ok and acceptable? Are there any less verbose options to solve it?

type Child_t (Id : Natural) is limited new Root_t (Id => Id) with
   record
     component : Component_t(Id => Id);
   end record;

Ada2012 controlled types error: call to abstract procedure must be dispatching

I'm facing a compilation error where I'm not sure about what is going on.

I provide a minimal reproducibable example; if I implement the Initialize procedure, everything is ok and no errors are thrown. The same occurs if class Derived_t has no Hashed_Maps instantiation component, which it's full view is a controlled type and I don't know if it could be related.

with Ada.Finalization;
private with Ada.Containers.Hashed_Maps;
private with Ada.Unchecked_Deallocation;

package root is
  
  type Root_t is limited interface;
  
  type Derived_t is abstract limited new Ada.Finalization.Limited_Controlled and
    Root_t with private;
  
  overriding
  procedure Initialize (this : in out Derived_t) is abstract; --if null implementation is provided, no error is raised
  
  overriding
  procedure Finalize (this : in out Derived_t);
  
private
  
  type array_t is array (Positive range <>) of Positive;
  type arrayPtr_t is access array_t;
  
  function fHash (key : Positive) return Ada.Containers.Hash_Type is
    (Ada.Containers.Hash_Type(key));
  
  package HashedDict_pck is new Ada.Containers.Hashed_Maps
    (Key_Type => Positive,
     Element_Type => Positive,
     Hash => fHash,
     Equivalent_Keys => "=");
  
  --The compilation error is raised before name Derived_t
  type Derived_t is abstract limited new Ada.Finalization.Limited_Controlled and
    Root_t with
     record
       arrayMember : arrayPtr_t;
       dict : HashedDict_pck.map;
     end record;
  
  procedure pFreeArray is new Ada.Unchecked_Deallocation
    (array_t, arrayPtr_t);

end root;
package body root is

  --------------
  -- Finalize --
  --------------

  overriding procedure Finalize (this : in out Derived_t) is
  begin
    this.dict.Clear;
    pFreeArray(this.arrayMember);
  end Finalize;

end root;

The compilation error occurs at line 33 column 8, just before entity name Derived_t in the private part: call to abstract procedure must be dispatching.

I know that controlled types are usually implemented privately, to hide the procedures to clients; I decided to make it public to enforce implementers of concrete classes to implement the Initialize procedure.

An implementer would do the following to implement a concrete class:

package root.concrete is

  type Concrete_t is new Derived_t with private;

  overriding
  procedure Initialize(this : in out Concrete_t); --Implementation will initialize Derived_t arrayMember

  --other Concrete_t public primitives

private

  type Concrete_t is new Derived_t with 
    record
      --Some stuff
    end record;

end root.concrete;

I think that, as I declare the map as a member record, and as the map is a controlled type, it needs to initialise its enclosing record but, as the Initialize is abstract, the compiler don't know what to call. Am I right?

I'll privatize the use of controlled types with a null default implementation of the Initialize to fix it, anyway an implementer shall implement the procedure for a concrete class to construct it correctly.

How to handle a GTK.CELL_RENDERER_TOGGLE into a GTK.TREE_STORE to activate/desactivate each row independiently

I have a TREE_MODEL in GTK. One of the columns is a GTK.CELL_RENDERER_TOGGLE to determine which rows are selected. I've tried to configure a Callback to activate/desactivate each toggle independiently but i have only achieved a callback that activate/desactivate the whole column. Is it possible?

package Q_SUBMIT_CHECKBOX_CALLBACK is new
   GTK.HANDLERS.USER_CALLBACK
   (WIDGET_TYPE => GTK.CELL_RENDERER_TOGGLE.GTK_CELL_RENDERER_TOGGLE_RECORD,
   USER_TYPE   => INTEGER);

GTK.TREE_VIEW_COLUMN.GTK_NEW (TREE_COLUMN => V_TREE_VIEW_COLUMN);

V_NUM :=
       GTK.TREE_VIEW.APPEND_COLUMN
           (TREE_VIEW => V_TREE,
            COLUMN    => V_TREE_VIEW_COLUMN);

GTK.CELL_RENDERER_TOGGLE.GTK_NEW (SELF => V_TOGGLE_RENDER);

GLIB.PROPERTIES.SET_PROPERTY
       (OBJECT => V_TOGGLE_RENDER,
        NAME   => GTK.CELL_RENDERER_TOGGLE.ACTIVATABLE_PROPERTY,
        VALUE  => TRUE);

GTK.TREE_VIEW_COLUMN.PACK_START
        (CELL_LAYOUT => V_TREE_VIEW_COLUMN,
         CELL        => V_TOGGLE_RENDER,
         EXPAND      => V_EXPAND);

Q_SUBMIT_CHECKBOX_CALLBACK.CONNECT
       (WIDGET    => V_TOGGLE_RENDER,
        NAME      => "toogled",
        MARSH     => Q_SUBMIT_CHECKBOX_CALLBACK.TO_MARSHALLER
           (P_CHECKBOX_CALLBACK'ACCESS),
        USER_DATA => 0);

Segmentation fault in Ada inline assembler [duplicate]

I'm taking my first steps in Ada and attempting to write a package which manipulates the CPUID instruction. I found some sequences on the OSDev wiki here for checking the EFLAGS.ID bit that I'm attempting to modify into an Ada function using inline assembler, but I'm running into a persistent segfault when trying to run it. First, the package spec & body:

-- Specification file: Cpuid.ads --

with Standard_Types; use Standard_Types;

package Cpuid is
    
    function Is_Supported return Boolean;

end Cpuid;

-- Body file: Cpuid.adb --

with System.Machine_Code; use System.Machine_Code;

package body Cpuid is

    function Is_Supported return Boolean is
        HT  : constant Character := Character'Val(16#09#);
        LF  : constant Character := Character'Val(16#0A#);
        EAX : Unsigned_32 := 16#0000_0000#;
    begin
        Asm ("pushfq"                    & LF & HT &
             "pushfq"                    & LF & HT &
             "popq    %%rax"             & LF & HT &
             "xorq    0x00200000, %%rax" & LF & HT &
             "pushq   %%rax"             & LF & HT &
             "popfq"                     & LF & HT &
             "pushfq"                    & LF & HT &
             "popq    %%rax"             & LF & HT &
             "xorq    (%%rsp), %%rax"    & LF & HT &
             "popfq"                     & LF & HT &
             "andq    0x00200000, %%rax" & LF & HT &
             "movl    %%eax, %0",
             Outputs  => Unsigned_32'Asm_Output ("=g", EAX),
             Volatile => True);
        if EAX /= 16#0000_0000# then 
            return True; 
        else 
            return False; 
        end if;
    end Is_Supported;

end Cpuid;

The Cpuid.Is_Supported function is called by a main program which looks like this:

with Ada.Text_IO;    use Ada.Text_IO;
with Standard_Types; use Standard_Types;
with Cpuid;

procedure Cpuid_Check is
    Some_Int : Unsigned_32 := 0;
begin
    if Cpuid.Is_Supported then
        Put_Line ("CPUID instruction supported on this CPU.");
    else
        Put_Line ("CPUID instruction not supported.");
    end if;
end Cpuid_Check;

Note that the Standard_Types import is just a spec-only package consisting of handwritten type definitions for Unsigned_8, Unsigned_16, and Unsigned_32.

When I attempt to run this program, the program fails with PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION. Using GDB allows me to trace the error to a SIGSEGV, but I am not able to trace the violation further to a particular instruction issuance. The full debugger output is as follows:

Temporary breakpoint 14, 0x00000000004016e0 in cpuid_check ()
[program stopped: breakpoint-hit]
(gdb) -exec-next
Single stepping until exit from function _ada_cpuid_check,
which has no line number information.
[program running]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401ede in cpuid.is_supported ()
[program stopped: signal-received]
(gdb) -exec-next
Single stepping until exit from function cpuid__is_supported,
which has no line number information.
[program running]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffc4d3473f9 in KERNEL32!IsBadReadPtr () from C:\Windows\System32\kernel32.dll
[program stopped: signal-received]
(gdb) 

I've checked to ensure that I'm leaving the stack "as I found it", which, to the best of my ability, appears to be the case - the same number of pushes and pops occur within the inline assembly section. I've also rearranged the assembly sequence into src, dest format, as my reading on GAS indicates that is the syntax used. In the process, however, I bamboozled myself - I'm more used to Intel/NASM syntax, and GAS looks like a mess in comparison.

Is there a way to rectify this function so that it functions properly?

EDIT: Here is the disassembly dump from GDB, as noted in the comments:

(gdb) disas
Dump of assembler code for function cpuid__is_supported:
   0x0000000000401ec4 <+0>: push   %rbp
   0x0000000000401ec5 <+1>: mov    %rsp,%rbp
   0x0000000000401ec8 <+4>: sub    $0x10,%rsp
   0x0000000000401ecc <+8>: movb   $0x9,-0x1(%rbp)
   0x0000000000401ed0 <+12>:    movb   $0xa,-0x2(%rbp)
   0x0000000000401ed4 <+16>:    movl   $0x0,-0x8(%rbp)
   0x0000000000401edb <+23>:    pushfq 
   0x0000000000401edc <+24>:    pushfq 
   0x0000000000401edd <+25>:    pop    %rax
=> 0x0000000000401ede <+26>:    xor    0x200000,%rax
   0x0000000000401ee6 <+34>:    push   %rax
   0x0000000000401ee7 <+35>:    popfq  
   0x0000000000401ee8 <+36>:    pushfq 
   0x0000000000401ee9 <+37>:    pop    %rax
   0x0000000000401eea <+38>:    xor    (%rsp),%rax
   0x0000000000401eee <+42>:    popfq  
   0x0000000000401eef <+43>:    and    0x200000,%rax
   0x0000000000401ef7 <+51>:    mov    %eax,%eax
   0x0000000000401ef9 <+53>:    mov    %eax,-0x8(%rbp)
   0x0000000000401efc <+56>:    cmpl   $0x0,-0x8(%rbp)
   0x0000000000401f00 <+60>:    je     0x401f09 <cpuid__is_supported+69>
   0x0000000000401f02 <+62>:    mov    $0x1,%eax
   0x0000000000401f07 <+67>:    jmp    0x401f0e <cpuid__is_supported+74>
   0x0000000000401f09 <+69>:    mov    $0x0,%eax
   0x0000000000401f0e <+74>:    nop
   0x0000000000401f0f <+75>:    nop
   0x0000000000401f10 <+76>:    add    $0x10,%rsp
   0x0000000000401f14 <+80>:    pop    %rbp
   0x0000000000401f15 <+81>:    retq   
   0x0000000000401f16 <+82>:    nop
   0x0000000000401f17 <+83>:    nop
   0x0000000000401f18 <+84>:    nop
   0x0000000000401f19 <+85>:    nop
   0x0000000000401f1a <+86>:    nop
   0x0000000000401f1b <+87>:    nop
   0x0000000000401f1c <+88>:    nop
   0x0000000000401f1d <+89>:    nop
   0x0000000000401f1e <+90>:    nop
   0x0000000000401f1f <+91>:    nop
End of assembler dump.

Ada2012: Assertion_Policy

According Ada2012 RM Assertion_Policy:

10.2/3 A pragma Assertion_Policy applies to the named assertion aspects in a specific region, and applies to all assertion expressions specified in that region. A pragma Assertion_Policy given in a declarative_part or immediately within a package_specification applies from the place of the pragma to the end of the innermost enclosing declarative region. The region for a pragma Assertion_Policy given as a configuration pragma is the declarative region for the entire compilation unit (or units) to which it applies.

This means that if I have a package hierarchy as per the following example:

└───Root
    ├───Child1
    ├───Child2
    │   └───GrandSon
    └───Child3

And if I define the pragma Assertion_Policy at Root package specification, it will affect to the whole package hierarchy right?

Ada instanciation of a generic package with an implementation of a limited interface

I have a limited interface defined in my_interface_package.ads.

package My_Interface_Package is

   type My_Interface is limited interface;

   procedure Procedure_1 (Some_Parameter : in out My_Interface) is null;
   procedure Procedure_2 (Some_Parameter_1 : in out My_Interface; Some_Parameter_2 : in String) is abstract;

end My_Interface_Package;

The type My_Class implements this interface (in my_class_package.ads and my_class_package.adb).

with My_Interface_Package;

package My_Class_Package is

   type My_Class is limited new My_Interface_Package.My_Interface with record
      Some_Element : Boolean;
   end record;

   overriding procedure Procedure_1 (Some_Parameter : in out My_Class);
   overriding procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String);

end My_Class_Package;
with Ada.Text_IO;

package body My_Class_Package is

   procedure Procedure_1 (Some_Parameter : in out My_Class) is
   begin
      Ada.Text_IO.Put_Line("Inside Procedure_1.");
   end;

   procedure Procedure_2 (Some_Parameter_1 : in out My_Class; Some_Parameter_2 : in String) is
   begin
      Ada.Text_IO.Put_Line("Inside Procedure_2.");
   end;

end My_Class_Package;

I have a generic package My_Generic_Package defined in my_generic_package.ads and my_generic_package.adb. It expects a type My_Generic_Type. I want this type to accept any concrete implementation of the interface My_Interface.

with My_Interface_Package;

generic
   type My_Generic_Type is limited new My_Interface_Package.My_Interface with private; -- The problem seems to be in this declaration.
package My_Generic_Package is

   type My_Generic_Class is record
      Element : My_Generic_Type;
   end record;

   procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class);
   procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String);

end My_Generic_Package;
with Ada.Text_IO;

package body My_Generic_Package is

   procedure Calling_Procedure_1 (Some_Parameter : in out My_Generic_Class) is
   begin
      Ada.Text_IO.Put_Line("Calling Procedure_1.");
      Procedure_1(Some_Parameter);
   end;

   procedure Calling_Procedure_2 (Some_Parameter_1 : in out My_Generic_Class; Some_Parameter_2 : in String) is
   begin
      Ada.Text_IO.Put_Line("Calling Procedure_2.");
      Procedure_2(Some_Parameter_1, Some_Parameter_2);
   end;

end My_Generic_Package;

My main.adb:

with Ada.Text_IO;
with My_Class_Package;
with My_Generic_Package;

procedure Main is
   package My_Instanciated_Package is new My_Generic_Package(My_Generic_Type => My_Class_Package.My_Class);
   My_Object : My_Instanciated_Package.My_Generic_Class;
begin
   My_Instanciated_Package.Calling_Procedure_1(My_Object);
   My_Instanciated_Package.Calling_Procedure_2(My_Object, "some_string");
   Ada.Text_IO.Put_Line("Program terminated.");
end Main;

GNAT 12.2.0 tells me my_generic_package.ads:3:73: missing ";" (he doesn't want the 'with private' part, but even without it, also fail).

I have tried a bunch of other declaration but ultimatly (trying to inspire myself from wikibooks), all failed. Any idea of what's wrong ?

Stack corruption in Ada C binding to OpenGL function

I'm using SDL to retrieve the address of the function. That much seems to be working, since I'm using the same subprogram that's working for all my other function calls.

Here are all the relevant code snippits in the spec:

type GLenum is new Uint32;

subtype glTexImage2D_Target is GLenum with Static_Predicate => glTexImage2D_Target in GL_TEXTURE_2D | GL_TEXTURE_RECTANGLE | GL_PROXY_TEXTURE_RECTANGLE;
subtype glTexImage2D_Dtype is GLenum with Static_Predicate => glTexImage2D_Dtype in GL_BYTE | GL_UNSIGNED_BYTE;
subtype glTexImage2D_InternalFormat is GLenum with Static_Predicate => glTexImage2D_InternalFormat in GL_DEPTH_COMPONENT | GL_DEPTH_STENCIL | GL_RED | GL_RG | GL_RGB | GL_RGBA;
subtype glTexImage2D_Format is GLenum with Static_Predicate => glTexImage2D_Format in GL_RED | GL_RG | GL_RGB | GL_BGR | GL_RGBA | GL_BGRA | GL_RED_INTEGER | GL_RG_INTEGER | GL_RGB_INTEGER | GL_BGR_INTEGER | GL_RGBA_INTEGER | GL_BGRA_INTEGER | GL_STENCIL_INDEX | GL_DEPTH_COMPONENT | GL_DEPTH_STENCIL;

procedure glTexImage2D(target : glTexImage2D_Target; level : Integer; internalFormat : glTexImage2D_InternalFormat; width : Integer; height : Integer; format : glTexImage2D_Format; dtype : glTexImage2D_Dtype; pixels : System.Address) with Pre => (target /= GL_TEXTURE_RECTANGLE and target /= GL_PROXY_TEXTURE_RECTANGLE) or Level = 0;

procedure Set_OpenGL_Subprogram_Address(Addr : in out System.Address; Name : String);

glTexImage2D_C_Address : System.Address := System.Null_Address;

Could_Not_Load_OpenGL_Subprogram : exception;

And here are the relevant snippits in the body:

procedure glTexImage2D(target : glTexImage2D_Target; level : Integer; internalFormat : glTexImage2D_InternalFormat; width : Integer; height : Integer; format : glTexImage2D_Format; dtype : glTexImage2D_Dtype; pixels : System.Address) is
begin
    Set_OpenGL_Subprogram_Address(glTexImage2D_C_Address, "glTexImage2D");
    declare
        procedure glTexImage2D_C(target : GLenum; level : GLint; internalFormat : GLint; width : GLsizei; height : GLsizei; border : GLint; format : GLenum; dtype : GLenum; data : System.Address)
        with Import, Convention => Stdcall, Address => glTexImage2D_C_Address;
    begin
        glTexImage2D_C(GLenum(target), GLint(level), GLint(internalFormat), GLsizei(width), GLsizei(height), GLint'(0), GLenum(format), GLenum(dtype), pixels);
    end;
end glTexImage2D;

--This seems to work... but here it is just in case.
procedure Set_OpenGL_Subprogram_Address(Addr : in out System.Address; Name : String) is
begin
    if Addr = System.Null_Address then
        Addr := SDL_GL_GetProcAddress(Value(New_String(Name)));
        if Addr = System.Null_Address then
            raise Could_Not_Load_OpenGL_Subprogram with Name;
        end if;
    end if;
end Set_OpenGL_Subprogram_Address;

Finally, the pixels I'm passing in is an address indicating an object of type:

type Uc_Array is array(Integer range <>) of aliased Interfaces.C.unsigned_char;

The stack is being corrupted on the call to glTexImage2D_C. I discovered this by using gdb:

enter image description here

Here you can see the parameters I'm passing as well; target 3553, level 0, internalformat 6408, width 63, height 63, format 6408, dtype 5121, non-zero pixels address. The subprogram address is being set to a non-zero value. But after the call to glTexImage2D_C, the value of $sp (the stack pointer) has increased by 16#24#.

I've tried adjusting the height and width I pass to glTexImage2D_C, both to 10 and both to 1000, just to see if giving it more (or less) buffer prevents stack corruption, but in every case, the stack pointer is different before and after the procedure call.

I'm hoping this is a simple matter of an incorrect datatype or something... Here's the prototype of glTexImage2D on the OpenGL side:

void glTexImage2D(  GLenum target,
    GLint level,
    GLint internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    GLenum format,
    GLenum type,
    const void * data);

(As a final note, I do intend to clean up the awkward lazy loading tactic you see above, if I can ever get this to actually work. For now I'm leaving it this way so I can eliminate the chance of trying to call a function that hasn't been loaded yet, while I'm still trying to debug the call itself. The tactic of using a nested procedure declared inside a declare...begin...end block is working for other OpenGL functions.)

Bug in GNAT Get(FRom => SomeString, Item => SomeInteger, Last => Last)?

Get(TheFile, IntValue); works great with strings formatted like 16#12# to read hex values. Shouldn't Get from a string function the same way?

I tried this, but passing 16#12# only yields 16. Pure hex, eg F8 results in an exception

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure hex is
   IntValue  : Integer;
   Last : Positive;
begin
   Put("Enter a hexadecimal string: ");
   Get(HexString);

   -- Convert the hexadecimal string to an integer
   Get(From => HexString, Item => IntValue, Last => Last);

   Put ("The integer value is: ");
   Put (IntValue, Width => 0);
   New_Line;
end hex;

❌
❌