Rick's message below implies that there is some contradiction between my
suggestion:
package P is
type T(<>) is private;
...
private
type T is array(Positive range <>) of Integer; -- Legal
end P;
and Steve Deller's observation (which I have reworded to make the
correspondence with my example more obvious):
package P is
type T is private;
...
private
type T is array(Positive range <>) of Integer; -- Illegal
end P;
There is no contradiction; these are not two "schools of thought". The
point is that if you wish to declare a private type whose full declaration
is "unconstrained" (also known as an "indefinite subtype") such as T above,
then you must declare the private type with an "unknown discriminant part",
the curious-looking "(<>)" syntax, as in my version. If you simply declare
a type as private as in Steve's example, without the unknown discriminant
part, then you can only complete it with a "constrained" type ("definite
subtype"), hence the error identified above.
Regards,
Ben
[log in to unmask]
-----Original Message-----
>From: Rick Duley <[log in to unmask]>
To: [log in to unmask] <[log in to unmask]>
Date: Thursday, February 04, 1999 11:32 PM
Subject: Re: Unconstrained Arrays problem
> I received suggestions from Ben Brosgol, Steven Deller, David Hoos
Sr, Sam
>Mize and Richard Riehle. Thanks folks for your rapid and helpful responses
>to my query.
>
>1. On the matter of declaration of Unconstrained Arrays as 'limited
>private' there are two schools of thought:
>
> Ben Brosgol reported:
>
>You can declare a private type with an "unknown discriminant part". The
>following example compiles and runs (I tried it under Aonix ObjectAda
>7.1.2):
>---
>package P is
> type T(<>) is private;
> function F(N : Integer) return T;
>private
> type T is array(Positive range <>) of Integer;
>end P;
>
>package body P is
> function F(N : Integer) return T is
> begin
> return T'(1..N => 0);
> end F;
>end P;
>
>with P; use P;
>procedure Test_Unconstrained is
> X : T := F(10);
>begin
> null;
>end Test_Unconstrained;
>
> and yet Steven Deller's response was:
>
>For item 1, my compiler tells me that for the following:
>
>package Trial3 is
> type Case_Type is (Open, Shut);
> type Uncon is private;
> procedure Dumb (X : in out Uncon);
>private
> type Uncon is array (Positive range <>) of Case_Type;
>end Trial3;
>
>" >>> Line 6: type Uncon is array (Positive range <>) of Case_Type"
>"*** array (Positive range <>) of Case_Type must be constrained [RM_95
>7.3(12)]" -- oops! missed that! :(
>
>When I read 7.3(12) it states that "..., then the full_type_declaration
>shall
>define a definite subtype" (and a definite subtype requires array bounds).
> That makes sense to me, since if code that used this package declared an
>object of type Uncon, there would be no way to determine the array bounds
>for
>that object.
>
>It is possible to use access types for Uncon, such that only the package
>body
>does any actual allocations of array entities, which may satisfy the
>original
>need you had:
>
>package Trial2 is
> type Case_Type is (Open, Shut);
> type Uncon is private;
>private
> type Uncon_array is array (Positive range <>) of Case_Type;
> type Uncon is access Uncon_array ;
>end Trial2;
>
>It is also possible to defer the definition of the Uncon_array into the
>body
>of the package:
>
>package Trial2 is
> type Case_Type is (Open, Shut);
> type Uncon is private;
> procedure Dumb (X : in out Uncon);
>private
> type Uncon_Array;
> type Uncon is access Uncon_Array;
>end Trial2;
>
>package body Trial2 is
> type Uncon_Array is array (Positive range <>) of Case_Type;
> procedure Dumb (X : in out Uncon) is
> begin
> if X = null then
> X := new Uncon_Array'(1 => Open, 2 => Shut);
> end if;
> end Dumb;
>end Trial2;
>
>
>2. Declaration of a constant: There were two main variations on
solutions.
>
> Always_Guilty : constant Court_Type := (2 .. 1 => Shut);
>
> as David Hoos commented "You have to specify a value for the array
>elements that aren't going to be there!"
>
> Alternatively, as Sam Mize suggested: "...you can just declare it
as a
>variable. After all, it's effectively constant -- you can't change any of
>the (non-existent) values!
>
> Never_Guilty: Court_Type (2..1);
>
> Richard Riehle made the point: "..., good
>object-oriented programming style would suggest that we abandon the
>use of deferred constants in our package designs. The usual form is
>something such as,
>
> package P is
> type T is private;
> Empty_T : constant T;
> -- more public stuff
> private
> full definitions of private stuff
> end P;
>
> "The more object-oriented way to approach this is to export a
function
>for Empty_T in place of the deferred constant.
>
> function Empty_T return T;
>
> "This allows a variety of implementations on Empty_T, eliminates
problems
>of dependencies when we change the values of the constants later, and
>improves maintainability. It also eliminates the need for the designer
>to fool around with syntax better left to the package implementor."
>
> It seems there _are_ ways around the matter. Once again, thanks to
all!
>
>-----------------------------------------------------------------------
> ______
>Rick Duley / \
>Edith Cowan University (____/\ )
>Perth, Western Australia |___ U?(____
> _\L. | \ ___
>ECU: +61 (08) 9370 6619 / /"""\ /.-' | |\ |
>mob: 0416 365 619 ( / _/u | \___|_)_|
> \| \\ / / \_(___ __)
> | \\ / / | | |
> | ) _/ / ) | |
> _\__/.-' /___( | |
>I think, _/ __________/ \ | |
>Therefore I am... // / ( ) | |
> ( \__|___\ \______ /__|____|
>I Think! \ (___\ |______)_/
> \ |\ \ \ /
> \ | \__ ) )___/
> \ \ )/ /__(
> ___ | /_//___| \_________
> _/ ( / OUuuu \
> `----'(____________)
>
|