GNAT errormessage question 
Author Message
 GNAT errormessage question

Dyn_Array_Test.adb:9:09: instantiation error at t.ads:14
Dyn_Array_Test.adb:9:09: controlled type must be declared at the library level

What is the meaning of this error message? What is
meant with library level?

Thanks
                Haug

PS: The source that produced the error.

with Ada.Finalization;
generic
        type Elem_Type is private;              
        Bound: in Positive;    
package t is
        type Dynamic_Array is tagged private;
private
   type Dynamic_Array is new Ada.Finalization.Controlled with
   record
        Elements        : Natural := 0;
   end record;
end t;

with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
with t;

procedure Dyn_Array_Test is

   procedure Test_Dyn_Array is
        package Dyn_Ustr_Array is new t ( Unbounded_String,Bound=>1000 );
        use Dyn_Ustr_Array;
        da: Dynamic_Array;
   begin
        null;
   end Test_Dyn_Array;

begin
        Test_Dyn_Array1;
end Dyn_Array_Test;



Thu, 13 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

But why does the declaration have to be at the library level?  Is this a
rule of Ada, or something specific to GNAT?

--

Nick Roberts
Croydon, UK

Proprietor, ThoughtWing Software; Independent Software Development
Consultant

*** Always game for a verbal joust (usually as the turkey) ***



Quote:


> >...What is
> >meant with library level?

> Basically, it means not nested inside any subprograms.

> In your example, you must move the instantiation of t out to such a
> place -- you could make the instantiation a library unit, or you could
> put it inside a library package.



Fri, 14 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

Quote:

> But why does the declaration have to be at the library level?  Is this a
> rule of Ada, or something specific to GNAT?

Because its parent is a tagged type (3.9.1(7)).  Yes. No.

/Jon

--
Jon Anthony
Synquiry Technologies, Ltd., Belmont, MA 02178, 617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari



Fri, 14 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

Many thanks for the comprehensive reply.  I had forgotten that the rule
applies wholesale to tagged types (as it sensibly must).

I have to say, with the benefit of hindsight, it might have been a better
decision to implement controlled types in a different way.  I feel sure
that -- by means of inlining -- undue performance penalties could be
avoided.  It is surely inconvenient, at times, not to be able to control
non-tagged types.  This ability may have been considered 'dangerous' or
unnecessary by the committee, but wrongly IMHO!

--

Nick Roberts
Croydon, UK

Proprietor, ThoughtWing Software; Independent Software Development
Consultant

*** Always game for a verbal joust (usually as the turkey) ***


Quote:
> It's not a special rule about controlled types (although that's what the
> GNAT error message might imply).  The rule is that when you have a type
> extension, "type T2 is new T1 with ...", T2 must be at the same nesting
> level as T1, where "nesting level" means dynamic nesting, like
> procedures, tasks and the like, and not static nesting, like packages.

> The reason for the rule is to avoid dangling references.  If you were
> allowed to write "type T2 is new T1 with ..." inside a procedure, where
> T1 is outside, then it would be possible to create an object whose tag
> is T2'Tag that outlive the procedure.  And then, after the procedure is
> gone, call something inside it, which might reference something in that
> long-gone procedure.  Bad news.

> The fact that this rule applies to controlled types is to some extent an
> artifact of the fact that controlled types are defined by saying "is new
> [Limited_]Controlled", rather than by some special syntax.  And *this*
> language design decision was made to simplify implementation (and
> language description).  We don't need all kinds of special semantics
> about controlled types -- most of it follows from the normal rules for
> type extensions.  Part of the issue is that the implementation can call
> Finalization without constructing some more-inner context for that call.



Sat, 15 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

: Many thanks for the comprehensive reply.  I had forgotten that the rule
: applies wholesale to tagged types (as it sensibly must).

: I have to say, with the benefit of hindsight, it might have been a better
: decision to implement controlled types in a different way.  I feel sure
: that -- by means of inlining -- undue performance penalties could be
: avoided.  It is surely inconvenient, at times, not to be able to control
: non-tagged types.  This ability may have been considered 'dangerous' or
: unnecessary by the committee, but wrongly IMHO!

Any kind of record or array may have controlled components.  I highly
recommend that you make individual components "clean up" after
themselves rather than relying on the root type being controlled.

By the way, Ada 95 was not designed by a committee.  It was designed by a
design team, and reviewed by Ada experts throughout the international
Ada community.

The decision to base controlled types on type extension was an attempt
to ensure a relatively straightforward implementation, where the
root controlled type would contain links for inserting the controlled
object on a linked list.  Ultimately, other considerations (such as
"mutable" discriminated types) pushed us to abandon the
links-through-the-object implementation model in our Ada 95 front end,
but I believe other compilers have taken advantage of the type
extension approach.

: Nick Roberts
: Croydon, UK

: Proprietor, ThoughtWing Software; Independent Software Development
: Consultant

--

Intermetrics, Inc.  Burlington, MA  USA



Sun, 16 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

Quote:

> The decision to base controlled types on type extension was an attempt
> to ensure a relatively straightforward implementation, where the
> root controlled type would contain links for inserting the controlled
> object on a linked list.  Ultimately, other considerations (such as
> "mutable" discriminated types) pushed us to abandon the
> links-through-the-object implementation model in our Ada 95 front end,
> but I believe other compilers have taken advantage of the type
> extension approach.

Could you elaborate a bit more on why you switched implementation models,
and how your front end implements them now? I used to hold the same view
as Nick, i.e. that this conflation of Controlled-ness and tagged-ness was
a flaw, and I changed my mind after trying to figure out alternative
approaches.

-- Brian



Sun, 16 Jul 2000 03:00:00 GMT  
 GNAT errormessage question


: >
: > The decision to base controlled types on type extension was an attempt
: > to ensure a relatively straightforward implementation, where the
: > root controlled type would contain links for inserting the controlled
: > object on a linked list.  Ultimately, other considerations (such as
: > "mutable" discriminated types) pushed us to abandon the
: > links-through-the-object implementation model in our Ada 95 front end,
: > but I believe other compilers have taken advantage of the type
: > extension approach.

: Could you elaborate a bit more on why you switched implementation models,
: and how your front end implements them now?

We originally planned to link all controlled objects, including components
of other objects, together in a linked list{*filter*} off a per-stack-frame
list header.  Now we create separate objects called "cleanup records",
which point to objects with any components requiring cleanup.  There
are several different kinds of cleanup records, one for a simple
controlled object, one for an array of controlled objects, one for
a heap of controlled objects, etc.  If a single local variable contains
multiple controlled components, the compiler synthesizes an overall
cleanup routine, and the cleanup record points to the local variable,
and to the synthesized cleanup routine.

There were two main reasons we went away from having each individual
controlled object or subcomponent on a linked list.  The first
had to do with "mutable" discriminated objects.  With mutable
discriminated object, such as a variant record with defaulted
discriminants, and assignment can have the effect of causing some
(potentially controlled) components go away, and others to come
into existence.  This meant that an assignment statement might
involve an arbitrary amount of delinking and relinking of
controlled subcomponents.  It also implied that the list of
controlled objects would have to be doubly linked rather than singly
linked, since we would have to remove and insert objects at
the middle of the list.

The second reason is that we decided that interoperability with
C++ would be reduced if every individual controlled object needed
to be linked onto a list.  "Early" C++ lacked exceptions, and
I'm not sure what C++ does with unions containing objects
with destructors, meaning that there were relatively easy
mechanisms for knowing what destructors needed to be
performed.  In any case, most C++ compilers still use "external"
information to keep track of what destructors need to be executed
at any given time, rather than linking the individual objects together.
This "external" information might be a linked list of something
like our cleanup records, or it might be mechanisms based on
counters which keep track of which destructors need to be performed.
objects, nor standard multithreading.
(still not part of the standard).
Probably the major rea

: ... I used to hold the same view
: as Nick, i.e. that this conflation of Controlled-ness and tagged-ness was
: a flaw, and I changed my mind after trying to figure out alternative
: approaches.

When we almost had everything working (now we really almost have everything
working ;-), we looked at the complexity of our cleanup record management,
and we pined for the "simplicity" of linking individual objects.
However, our cleanup record mechanism is now quite
robust, and we have found it able to handle all of the various
feature interactions involving exceptions, finalization, functions
with unconstrained result subtypes, protected types, classwide types
in the heap, abort and async transfer of control, etc.  It is fairly
efficient, though there are probably even more complex schemes that
could be cooked up which would be somewhat more efficient.

We definitely take advantage of the fact that all user-defined
finalization routines are library-level procedures.  If we had
to worry about static links or global displays for user-defined
finalization routines, it could really do us in.  So even though
we don't take advantage of type extension directly, we do take
advantage of the requirement that all controlled types be defined
at the library level.  The benefit of that requirement is reduced
somewhat by the fact that record types requiring compiler-synthesized
cleanup routines can be defined at a nested level.  However, we have
more control over those and we can avoid the need for a static link
parameter or a properly managed global display in the synthesized routines.

: -- Brian

--

Intermetrics, Inc.  Burlington, MA  USA



Mon, 17 Jul 2000 03:00:00 GMT  
 GNAT errormessage question

Just as a postscript here, GNAT *does* use the linked list approach that
Tuck mentions and that the RM originally had in mind :-)



Thu, 20 Jul 2000 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. variables with space causes errormessages?!

2. Cookie gets me an errormessage I don't understand

3. Errormessages

4. complaint about tcl errormessages

5. Next Generation GNAT ... GNAT Pro 5.00a

6. Status of GCC-GNAT versus GNAT 3.14-3.15

7. Bug in GNAT.Socket.Check_Selector in GNAT 3.14 Linux runtime

8. source for Gnat and gnat- Glade

9. Gnat Chat, Random Numbers in GNAT

10. GNAT probem (should have been on chat@gnat)

11. ANNOUNCE : Win32Ada patch for GNAT 3.09 and GNAT 3.10a (Windows 95/NT)

12. GNAT 3.07 v. GNAT 3.09

 

 
Powered by phpBB® Forum Software