Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"subprogram must not be deeper than access type"

97 views
Skip to first unread message

andrew...@gmail.com

unread,
Oct 3, 2020, 12:39:27 AM10/3/20
to
Hello,

I'm trying my hand at a small rosettacode.org example:

https://codeshare.io/an080j

What I don't understand is when I'm creating the various packages to serve as handlers, I get the following compile-time errors:

gprbuild : event_handlers_window.adb:13:03: instantiation error at gtk-handlers.ads:1039
event_handlers_window.adb:13:03: subprogram must not be deeper than access type
event_handlers_window.adb:14:03: instantiation error at gtk-handlers.ads:437
event_handlers_window.adb:14:03: subprogram must not be deeper than access type

How am I making a subprogram deeper than an access type exactly?

Dmitry A. Kazakov

unread,
Oct 3, 2020, 2:42:01 AM10/3/20
to
The access type to the handler function is declared at the library
level. Your handler subprogram is declared inside the body of
Event_Handlers_Window, which is one step deeper than the library level.

You can:

1. Move the handler function into a package. A library package would be
on the same level with the access type declaration. That is the
recommended way.

2. You can circumvent accessibility checks by declaring a local access
type to the function in the procedure (which would be same level) and
then convert from this type to the handler type using
Unchecked_Conversion. This is not recommended, obviously.

3. Specifically for delete and destroy events in GtkAda Contributions
the package Gtk.Missed defines ready-to-use handlers as in the solution #1.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

andrew...@gmail.com

unread,
Oct 6, 2020, 12:00:32 AM10/6/20
to
Hi Dmitry,

Thanks for writing back.

I guess I'm not sure what you mean by #1. The handler package contains another package, Callback. And the compiler never really gets to the methods (Destroy and Delete_Event), it stops when I try to create a new package from an existing one. Could you please show me an example of what you mean?

Also, I looked through the docs and couldn't find Gtk.Missed... did you mean some other method/package?

Thank you,
--Andrew

Dmitry A. Kazakov

unread,
Oct 6, 2020, 2:08:08 AM10/6/20
to
On 06/10/2020 06:00, andrew...@gmail.com wrote:
> On Saturday, October 3, 2020 at 2:42:01 AM UTC-4, Dmitry A. Kazakov wrote:

> I guess I'm not sure what you mean by #1. The handler package contains another package, Callback. And the compiler never really gets to the methods (Destroy and Delete_Event), it stops when I try to create a new package from an existing one.

It stops on compiling a call to connect a handler to the event. The
handler is declared deeper than the pointer the event uses to refer to
the handler. The language requires that in order to prevent the
situation when the handler ceases to exist but the event still may be
emitted.

> Could you please show me an example of what you mean?
-----------------------------------------------------------------
with Gtk.Widget; use Gtk.Widget;

package My_Handlers is
function Delete_Event (Widget : access Gtk_Widget_Record'Class)
return Boolean;
procedure Destroy (Widget : access Gtk_Widget_Record'Class);
end My_Handlers;
-----------------------------------------------------------------
with Gtk.Main;

package body My_Handlers is
function Delete_Event (Widget : access Gtk_Widget_Record'Class)
return Boolean is
begin
return False;
end Delete_Event;

procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
begin
Gtk.Main.Main_Quit;
end Destroy;
end My_Handlers;
-----------------------------------------------------------------
with Gtk.Label;
with Gtk.Window;
with Gtk.Widget;
with Gtk.Handlers;
with Gtk.Main;
with My_Handlers;

procedure Event_Handlers_Window is
Window : Gtk.Window.Gtk_Window;
Label : Gtk.Label.Gtk_Label;
begin
Gtk.Main.Init;
Gtk.Window.Gtk_New (Window);
Gtk.Label.Gtk_New (Label, "Goodbye, World!");
Gtk.Window.Add (Window, Label);
Window.On_Delete (My_Handlers.Delete_Event'Access); -- Connect handler
Window.On_Destroy (My_Handlers.Destroy'Access);

Gtk.Label.Show_All (Label); -- Could drop this and use
Gtk.Window.Show (Window); -- Show_All here

Gtk.Main.Main;
end Event_Handlers_Window;
-----------------------------------------------------------------
> Also, I looked through the docs and couldn't find Gtk.Missed... did you mean some other method/package?

http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#5

Scroll down to the declarations of

Delete_Event_Handler
Destroy_Handler
0 new messages