From: Hibou57 (Yannick Duchêne) on

Hi,

I may be not lucky : after the case of an object of a protected type being
finalized too much soon, here is now that I have to do with an object of a
protected type which never gets finalized (think I was to use this latter
as a work around after long try failure with the former, I'm really not
lucky at all).

Inquisitive peoples with interests in the case, may have a look at the
following test : two protected types are defined, with exact equivalent
definition. One is defined in a package, the other is defined in the local
scope. An instance of the first (the one defined in the package), never
get finalized. An instance of the second type (declared in the local
scope), goes through its normal life.

But perhaps there's something I did not understood


with Ada.Text_IO;
with Ada.Finalization;

procedure Test is
-- This test program exposes a protected
-- object which is initialized, but never
-- get finalized (object of type A_Type).

-- Don't care starting here if you just want to
-- have a quick look, jump to the comment
-- "Important things starts here" later below.

package Spies is
type Instance_Type (Client_Name : access String) is
limited private;
private
type Instance_Type (Client_Name : access String) is
new Ada.Finalization.Limited_Controlled
with null record;
overriding procedure Initialize
(Instance : in out Instance_Type);
overriding procedure Finalize
(Instance : in out Instance_Type);
end Spies;

package body Spies is
overriding procedure Initialize
(Instance : in out Instance_Type)
is
Me : Instance_Type renames Instance;
begin
Ada.Text_IO.Put_Line
("Spy : I am coping with Initialization of " &
Me.Client_Name.all &
".");
end;
overriding procedure Finalize
(Instance : in out Instance_Type)
is
Me : Instance_Type renames Instance;
begin
Ada.Text_IO.Put_Line
("Spy : I am coping with Finalization of " &
Me.Client_Name.all &
".");
end;
end Spies;

-- Important things starts here

package P is
type A_Type is limited private;
private
protected type A_Type is
private
Spy : Spies.Instance_Type
(Client_Name => new String'("P.A_Type"));
end;
end P;

package body P is

protected body A_Type is
end;

end P;

protected type B_Type is
private
Spy : Spies.Instance_Type
(Client_Name => new String'("B_Type"));
end;

protected body B_Type is
end;

begin
declare
Tested_Object : P.A_Type;
begin
Ada.Text_IO.Put_Line ("Inside block testing A_Type");
-- Tested_Object is initialized, but never
-- get finalized, while [ARM 7.6.1(8)] requires
-- finalization for protected types. Or am I wrong ?
end;

Ada.Text_IO.New_Line;

declare
Tested_Object : B_Type;
begin
Ada.Text_IO.Put_Line ("Inside block testing B_Type");
-- This one, with a strictly equivalent declaration, which
-- is just not declared inside a package, get finalized
-- as expected.
end;
end Test;
From: John B. Matthews on
In article <op.u71i2edlvwnd5a(a)garhos>,
Hibou57 (Yannick Duchêne) <yannick_duchene(a)yahoo.fr> wrote:

> I may be not lucky : after the case of an object of a protected type
> being finalized too much soon, here is now that I have to do with an
> object of a protected type which never gets finalized (think I was
> to use this latter as a work around after long try failure with the
> former, I'm really not lucky at all).
>
> Inquisitive peoples with interests in the case, may have a look at
> the following test : two protected types are defined, with exact
> equivalent definition. One is defined in a package, the other is
> defined in the local scope. An instance of the first (the one
> defined in the package), never get finalized. An instance of the
> second type (declared in the local scope), goes through its normal
> life.
>
> But perhaps there's something I did not understood

I get the same result with gcc 4.3.4, but it works if protected type
A_Type is public in P:

package P is
protected type A_Type is
private
Spy : Spies.Instance_Type
(Client_Name => new String'("P.A_Type"));
end;
end P;

Type A_Type has its own private part, and this seems more comparable to
the declaration of protected type B_Type. Is there any reason to make
A_Type more opaque?

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
From: sjw on
On Feb 14, 12:35 pm, "John B. Matthews" <nos...(a)nospam.invalid> wrote:

> I get the same result with gcc 4.3.4, but it works if protected type
> A_Type is public in P:
>
>    package P is
>       protected type A_Type is
>       private
>           Spy : Spies.Instance_Type
>             (Client_Name => new String'("P.A_Type"));
>       end;
>    end P;
>
> Type A_Type has its own private part, and this seems more comparable to
> the declaration of protected type B_Type. Is there any reason to make
> A_Type more opaque?

I had wanted to write

private
Name : aliased constant String := "P.A_Type";
protected type A_Type is
private
Spy : Spies.Instance_Type
(Client_Name => Name'Access);
end;
end P;

to avoid allocating a new Client_Name at each instance creation. This
looks a little messy if in the public part.
From: Hibou57 (Yannick Duchêne) on
Le Sun, 14 Feb 2010 13:35:47 +0100, John B. Matthews
<nospam(a)nospam.invalid> a écrit:
> Type A_Type has its own private part, and this seems more comparable to
> the declaration of protected type B_Type. Is there any reason to make
> A_Type more opaque?
>
Well, let say first I don't like the idea of designing with a compiler bug
is mind, and secondly, this is not to be part of a public part (I don't
really like private stuff in public part).
When I know a mostly clean workaround, that's Ok, but I do not like this
one.
TBH, as was trying (as explained in the initial post), to workaround
another bug when I meet this one.
The interesting point to me, is that you get the same, so it is not just
my compiler. This means for me I should report the bug to AdaCore (as you
seem to have confirmed the bug).

I thank you for the test you've made :)

--
No-no, this isn't an oops ...or I hope (TM) - Don't blame me... I'm just
not lucky
From: Hibou57 (Yannick Duchêne) on
Le Mon, 15 Feb 2010 19:08:18 +0100, sjw <simon.j.wright(a)mac.com> a écrit:
> I had wanted to write
>
> private
> Name : aliased constant String := "P.A_Type";
> protected type A_Type is
> private
> Spy : Spies.Instance_Type
> (Client_Name => Name'Access);
> end;
> end P;
>
> to avoid allocating a new Client_Name at each instance creation.
Don't bother, this String is just required for the Spy member, which was
just there to test how things was working. This was not to be part of the
final application.

> This looks a little messy if in the public part.
Yes, ;)


--
No-no, this isn't an oops ...or I hope (TM) - Don't blame me... I'm just
not lucky