comp.lang.ada
 help / color / mirror / Atom feed
* Finalization and class-wide views
@ 2016-06-15 23:50 Alejandro R. Mosteo
  2016-06-16  7:34 ` Dmitry A. Kazakov
  2016-06-16 11:10 ` Alejandro R. Mosteo
  0 siblings, 2 replies; 5+ messages in thread
From: Alejandro R. Mosteo @ 2016-06-15 23:50 UTC (permalink / raw)


Dear all,

while pursuing a memory leak I've found a subtle difference in 
Controlled behavior in the latest Gnat GPL when using operators vs 
regular functions. Now, this could well be a misunderstanding on my part 
on how these things work, but the implications for a real program I'm 
working on are so that I can't really move forward without properly 
understanding it. I've tried the ARM but couldn't arrive at a firm 
conclusion.

In my program, the outcome is that, for some class-wide types, 
finalization of its controlled members is delayed past their proper 
lifetime until program termination, generating a memory leak. I have 
attempted to reproduce it in a self-contained case, but the result is 
not identical. Here, it seems a finalization is missing altogether (I 
know by now you're skeptical of me ;-)

See below for the output and explanation, if you prefer, before taking a 
look at the code (compiled with -Og):

with Ada.Finalization; use Ada.Finalization;
with Ada.Text_Io; use Ada.Text_Io;

procedure Finalize_Leak is
    generic
    package P is

       type One is interface;

       type Managed is new Controlled with record
          X : Integer := 1;
       end record;
       overriding procedure Finalize (M : in out Managed);

       type Two is new One with record
          M : Managed;
       end record;

    end P;

    package body P is
       overriding procedure Finalize (M : in out Managed) is
          pragma Unreferenced (M);
       begin
          Put_Line ("finalize M");
          M.X := 0;
       end Finalize;
    end P;

    package PP is new P; use PP;

    function Pass  (X : Two'Class) return One'Class is (X);
    function "not" (X : Two'Class) return One'Class is (X);

    A : Two;
begin
    declare
       B : constant One'Class := A;
    begin
       Put_Line ("---8<---");
       Put_Line (Two'Class (B).M.X'Img);
    end;
    Put_Line ("--->8---");

    New_Line;
    declare
       B : constant One'Class := Pass (A);
    begin
       Put_Line ("---8<---");
       Put_Line (Two'Class (B).M.X'Img);
    end;
    Put_Line ("--->8---");

    New_Line;
    A.M.X := 2;
    declare
       B : One'Class := not A;
    begin
       Put_Line ("---8<---");
       Put_Line (Two'Class (B).M.X'Img);
    end;
    Put_Line ("--->8---");

    New_Line; Put_Line ("Now A is going to finalize");
end Finalize_Leak;


*So.*

I would expect the three declare blocks to produce more or less (besides 
temporaries) the same output: One "finalize" printed between each 
matching scissor pair, corresponding to B going out of scope. In other 
words, the conversion to an ancestor does not cause the finalization of 
the full view type (this was my belief until now, otherwise how could 
containers of classwide types work?). Instead, the output I get is:

---8<---
  1
finalize M
--->8---

finalize M
---8<---
  1
finalize M
--->8---

finalize M
---8<---
  2
--->8---

Now A is going to finalize
finalize M

So the first declare is straightforward, the second one seems to involve 
a temporary somewhere, and (here is my hope that this is not normal) the 
last one, where seemingly B.M finalization seems missing. The integer 
tells me that the previous finalization is of a temporary.

I hope some of you experts can shed some light. To summarize: do 
class-wide conversions affect finalization? Do you smell something fishy 
in this case?

Thanks in advance,
Alex.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-06-17 10:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-15 23:50 Finalization and class-wide views Alejandro R. Mosteo
2016-06-16  7:34 ` Dmitry A. Kazakov
2016-06-16  9:11   ` Alejandro R. Mosteo
2016-06-16 11:10 ` Alejandro R. Mosteo
2016-06-17 10:22   ` Alejandro R. Mosteo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox