comp.lang.ada
 help / color / mirror / Atom feed
* warning: Storage_Error will be raised at run-time
@ 1997-12-15  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-12-15  0:00 ` Robert Dewar
  1997-12-15  0:00 ` Tucker Taft
  0 siblings, 2 replies; 6+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-12-15  0:00 UTC (permalink / raw)



    Maybe this one has been dealt with before. Using GNAT (GNAT 3.09 -
    Sun Unix) I compile the attached code and get the following error
    messages:

procedure Test is

    type Variant_Type (Size : Natural := 0) is record
        Count    : Natural ;
        Table    : String (1..Size) ;
    end record ;

    Variant : Variant_Type ;
begin
    null ;
end Test ;

test.adb:5:31: warning: creation of object of this type may raise Storage_Error
test.adb:8:05: warning: Storage_Error will be raised at run-time

    My best guess is that the implementation takes a look at the
    "(Size : Natural := 0)" part and decides that it needs to allocate
    1..Natural'Last bytes for the Table field of every object of type
    Variant_Type. I can see how this would make it simple to handle
    assignments to objects of type Variant_Type since they would have
    already allocated memory for the worst case scenario. This seems
    like a bad implementation choice in that, while it may be very
    fast, doesn't allow the user much leeway. (This seems to be the
    case even when you declare an object with a fixed discriminant and
    an initial expression. It still wants to allocate for the worst
    case, presumably in anticipation of reassignment to the object. Or
    is it something else altogether?)

    I'd like to not constrain the size of the discriminated record to
    some arbitrarily small number via use of a subtype for the
    discriminant. Is there a known method of sneaking around this? If
    I allocate all objects from the heap dynamically, will it restrict
    the space to just what is requested? (Seems like that would have
    to handle reassignment too - or is there a language rule I'm
    forgetting?) Or is there some option or pragma I've missed which
    changes the allocation rules?

    While this sort of static allocation may be simple to implement
    and fast at run time, it seems to defeat a major purpose of
    discriminated records: the ability to allocate just what you need
    at run time to accomodate widely varying space demands. Otherwise,
    why not just go with a fixed size array in the record since that's
    what you're going to get anyway?

    MDC

Marin David Condic, Senior Computer Engineer     Voice:     561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:       561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:  CONDICMA@PWFL.COM
===============================================================================
    Glendower: "I can call spirits from the vasty deep."
    Hotspur: "Why so can I, or so can any man; but will they come when
    you do call for them?"
        -- Shakespeare, "Henry IV"
===============================================================================




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

* Re: warning: Storage_Error will be raised at run-time
  1997-12-15  0:00 warning: Storage_Error will be raised at run-time Marin David Condic, 561.796.8997, M/S 731-96
  1997-12-15  0:00 ` Robert Dewar
@ 1997-12-15  0:00 ` Tucker Taft
  1 sibling, 0 replies; 6+ messages in thread
From: Tucker Taft @ 1997-12-15  0:00 UTC (permalink / raw)



Marin David Condic, 561.796.8997, M/S 731-96 (condicma@PWFL.COM) wrote:

:     Maybe this one has been dealt with before. Using GNAT (GNAT 3.09 -
:     Sun Unix) I compile the attached code and get the following error
:     messages:

: procedure Test is

:     type Variant_Type (Size : Natural := 0) is record
:         Count    : Natural ;
:         Table    : String (1..Size) ;
:     end record ;

:     Variant : Variant_Type ;
: begin
:     null ;
: end Test ;

: test.adb:5:31: warning: creation of object of this type may raise Storage_Error
: test.adb:8:05: warning: Storage_Error will be raised at run-time

:     My best guess is that the implementation takes a look at the
:     "(Size : Natural := 0)" part and decides that it needs to allocate
:     1..Natural'Last bytes for the Table field of every object of type
:     Variant_Type. I can see how this would make it simple to handle
:     assignments to objects of type Variant_Type since they would have
:     already allocated memory for the worst case scenario. This seems
:     like a bad implementation choice in that, while it may be very
:     fast, doesn't allow the user much leeway. 

The alternative is to use the heap implicitly when an assignment
needs to enlarge the object.  This approach was adopted by Alsys
under some conditions in their Ada 83 product, and something similar
is supported by RR (and Meridian Ada 83) by using a level of indirection for 
nested arrays, but most other vendors did not embrace this approach.
I believe the main reason is that implicit use of the heap, particularly
as a side effect of a relatively "benign" looking operation like
assignment, is a no-no in a real-time/safety-critical language.

In Ada 95, if you want this kind of automatic "growing" data structure,
then you can program it using controlled types.  That seems like
a better solution to me, because it gives the programmer full,
explicit control over any use of the heap.

: ...
:     While this sort of static allocation may be simple to implement
:     and fast at run time, it seems to defeat a major purpose of
:     discriminated records: the ability to allocate just what you need
:     at run time to accomodate widely varying space demands. Otherwise,
:     why not just go with a fixed size array in the record since that's
:     what you're going to get anyway?

The purpose of discriminated records is not so much to accomodate individual
growing objects, but rather to accommodate multiple objects of different 
sizes, which are nevertheless all of the same type.  

Furthermore, given our recent news thread on the implicit overhead
of holey enumeration types, you can be sure someone would be complaining
about the implicit overhead of assigning to unconstrained discriminated 
records.  Implicit overhead is almost always bad news, IMHO.
If there is to be overhead, the programmer ought to be explicitly writing
and controlling the implementation of that "overhead" computation.

:     MDC

: Marin David Condic, Senior Computer Engineer     Voice:     561.796.8997
: Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:       561.796.4669
: West Palm Beach, FL, 33410-9600                  Internet:  CONDICMA@PWFL.COM
: ===============================================================================
:     Glendower: "I can call spirits from the vasty deep."
:     Hotspur: "Why so can I, or so can any man; but will they come when
:     you do call for them?"
:         -- Shakespeare, "Henry IV"
: ===============================================================================

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




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

* Re: warning: Storage_Error will be raised at run-time
  1997-12-15  0:00 warning: Storage_Error will be raised at run-time Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-12-15  0:00 ` Robert Dewar
  1997-12-15  0:00 ` Tucker Taft
  1 sibling, 0 replies; 6+ messages in thread
From: Robert Dewar @ 1997-12-15  0:00 UTC (permalink / raw)



Marin says

<<    My best guess is that the implementation takes a look at the
    "(Size : Natural := 0)" part and decides that it needs to allocate
    1..Natural'Last bytes for the Table field of every object of type
    Variant_Type. I can see how this would make it simple to handle
    assignments to objects of type Variant_Type since they would have
    already allocated memory for the worst case scenario. This seems
    like a bad implementation choice in that, while it may be very
    fast, doesn't allow the user much leeway. (This seems to be the
    case even when you declare an object with a fixed discriminant and
    an initial expression. It still wants to allocate for the worst
    case, presumably in anticipation of reassignment to the object. Or
    is it something else altogether?)
>>

This is an old discussion, and one on which compilers have historically
disagreed. There are two viewpoints:

1. Implicit heap allocation is to be avoided, if you want to handle variable
length objects using pointers and dynamic allocation, it should be done 
exoplicitly in the code.

2. It is fine to use implicit heap allocations and implicit pointers.

Many Ada compilers have preferred approach 1 in the past (e.g. DEC Ada),
and that is the approach that GNAT takes, so the maximum space is always
allocated statically. I believe that the Intermetrics compiler takes the
same approach.

Using dynamic allocation can result in some nasty implementation problems,
since to do it right, you need to have non-contiguous representations. Alsys
used dynamic allocation on only one level, so you could declare these mutant
objects at the outer level, but you could not have arrays of them, because for
arrays they allocated the maximum size and restricted it to a small value.

RR tried to do the dynmaic allocation fully resulting in non=contiguous
objects, but at least at one point, would output warnings that storage
leaks could result.

I think it is clear that the maximum space allocation is the right choice.

If you want dynamic allocation, and poiners, use NEW and ACCESS!





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

* Re: warning: Storage_Error will be raised at run-time
@ 1997-12-16  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-12-16  0:00 ` Robert Dewar
  1997-12-16  0:00 ` Tucker Taft
  0 siblings, 2 replies; 6+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-12-16  0:00 UTC (permalink / raw)



Tucker Taft <stt@HOUDINI.CAMB.INMET.COM> writes:
>: ...
>:     While this sort of static allocation may be simple to implement
>:     and fast at run time, it seems to defeat a major purpose of
>:     discriminated records: the ability to allocate just what you need
>:     at run time to accomodate widely varying space demands. Otherwise,
>:     why not just go with a fixed size array in the record since that's
>:     what you're going to get anyway?
>
>The purpose of discriminated records is not so much to accomodate individual
>growing objects, but rather to accommodate multiple objects of different
>sizes, which are nevertheless all of the same type.
>
    I think that was kind of what I was shooting at: I may need one
    object with 5 characters in it and another object with a thousand.
    If that means that all objects of the type have to allocate a
    thousand bytes, then it seems like you loose any advantage of
    having a discriminant - just allocate the string to be a thousand
    bytes long from the get-go. The DEC Ada compiler at least gives
    the appearance of doing what I'm looking for in this case - at
    least it never issued any warnings about Storage_Error.

    Is there any way to coerce the compiler into the behavior I want?
    (Allocating what I request off of the stack?)

>Furthermore, given our recent news thread on the implicit overhead
>of holey enumeration types, you can be sure someone would be complaining
>about the implicit overhead of assigning to unconstrained discriminated
>records.  Implicit overhead is almost always bad news, IMHO.
>If there is to be overhead, the programmer ought to be explicitly writing
>and controlling the implementation of that "overhead" computation.
>
    Yeah. And the bad news is that I'd probably be one of them
    complaining about speed. Of course in the particular case I'm
    dealing with at the moment, I'm building a fairly straightforward
    application on a Sun with no realtime constraints. Hence, dynamic
    behavior is not much of a concern - but wantonly wasting memory
    is.

    What would be nice is having some method of toggling between one
    implementation method and the other - perhaps a pragma? Or would
    it be more sensible to invent a different kind of "record" type
    which did dynamic allocation?

    MDC

Marin David Condic, Senior Computer Engineer     Voice:     561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:       561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:  CONDICMA@PWFL.COM
=============================================================================
    "Outside of a dog, a book is man's best friend; inside a dog,
    it's too dark to read..."
        --  Groucho Marx
=============================================================================




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

* Re: warning: Storage_Error will be raised at run-time
  1997-12-16  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-12-16  0:00 ` Robert Dewar
@ 1997-12-16  0:00 ` Tucker Taft
  1 sibling, 0 replies; 6+ messages in thread
From: Tucker Taft @ 1997-12-16  0:00 UTC (permalink / raw)



Marin David Condic, 561.796.8997, M/S 731-96 (condicma@PWFL.COM) wrote:

: Tucker Taft <stt@HOUDINI.CAMB.INMET.COM> writes:

: >The purpose of discriminated records is not so much to accomodate individual
: >growing objects, but rather to accommodate multiple objects of different
: >sizes, which are nevertheless all of the same type.
: >
:     I think that was kind of what I was shooting at: I may need one
:     object with 5 characters in it and another object with a thousand.
:     If that means that all objects of the type have to allocate a
:     thousand bytes, then it seems like you loose any advantage of
:     having a discriminant - just allocate the string to be a thousand
:     bytes long from the get-go. The DEC Ada compiler at least gives
:     the appearance of doing what I'm looking for in this case - at
:     least it never issued any warnings about Storage_Error.

:     Is there any way to coerce the compiler into the behavior I want?
:     (Allocating what I request off of the stack?)

All you need to do is specify the value of the discriminant
at the point of declaration.  It is only if you allow the
discriminant to default that the compiler will allocate
the maximum possible, since it is only then that you
are allowed to change the size of the object as a side-effect
of assignment.

I presume GNAT is giving you the warning because you specified
a default for the discriminant.  Just leave out the default,
and I suspect the warning will go away.  GNAT is reasonably
presuming that if you give a default, you might take advantage
of it some day.  However, if you do use the default, you
will get a *very* large object, because the subtype of the
discriminant has a huge range.  If you do want to take
advantage of the default, then you should declare a subtype
with a narrower range.  GNAT will compute the max size needed
and find it tolerable, and thereby not give you the warning.

I believe the implementation approach of GNAT, DEC, and our
front end are all the same.  The only difference is that GNAT
gives you a warning when you give a default for a discriminant
that has a huge subtype range, while the others give you the bad news
when you take advantage of the default (i.e. at an object
declaration without an explicit discriminant).  The GNAT warning
seems pretty "friendly" to me, but you never know with warnings...


: Marin David Condic, Senior Computer Engineer     Voice:     561.796.8997
: Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:       561.796.4669
: West Palm Beach, FL, 33410-9600                  Internet:  CONDICMA@PWFL.COM

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




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

* Re: warning: Storage_Error will be raised at run-time
  1997-12-16  0:00 Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-12-16  0:00 ` Robert Dewar
  1997-12-16  0:00 ` Tucker Taft
  1 sibling, 0 replies; 6+ messages in thread
From: Robert Dewar @ 1997-12-16  0:00 UTC (permalink / raw)



Marin says

<<    I think that was kind of what I was shooting at: I may need one
    object with 5 characters in it and another object with a thousand.
    If that means that all objects of the type have to allocate a
    thousand bytes, then it seems like you loose any advantage of
    having a discriminant - just allocate the string to be a thousand
    bytes long from the get-go. The DEC Ada compiler at least gives
    the appearance of doing what I'm looking for in this case - at
    least it never issued any warnings about Storage_Error.
>>

I guess ignorance is bliss :-)
GNAT and DEC Ada 83 have exactly the same implementation model here. You may
not get warnings about SE from DEC Ada 83, but you will certainly get the
SE if you do not use an explicit discriminant!

(in the case we are talking about)

<<    Is there any way to coerce the compiler into the behavior I want?
    (Allocating what I request off of the stack?)
>>

Well if you want an individual variable to be a particular size, then
just constrain it appropriately, and the proper amount of space will
be allocated, but if you want to be free to reassign different lengths,
then it is of coruse NOT possible to assign the space from the stack 
(think about it for a bit, and I think you will see that the only way
to do this is to have hidden implicit heap allocation).






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

end of thread, other threads:[~1997-12-16  0:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-12-15  0:00 warning: Storage_Error will be raised at run-time Marin David Condic, 561.796.8997, M/S 731-96
1997-12-15  0:00 ` Robert Dewar
1997-12-15  0:00 ` Tucker Taft
  -- strict thread matches above, loose matches on Subject: below --
1997-12-16  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-12-16  0:00 ` Robert Dewar
1997-12-16  0:00 ` Tucker Taft

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