comp.lang.ada
 help / color / mirror / Atom feed
From: Kirk Beitz <johndoe@world.std.com>
To: kroemer@iabg.de
Subject: Re: Help with gnat storage error
Date: 1997/06/24
Date: 1997-06-24T00:00:00+00:00	[thread overview]
Message-ID: <33AF98EB.73C2@world.std.com> (raw)
In-Reply-To: 5olggu$dcg$1@cdserv.rzg.mpg.de


Myriam Witt wrote:
> 
> Hello....
> 
> I'm using gnat's binary distribution
> gnat-3.09-sparc-sun-solaris2.4-bin.tar.gz
> on a SUN Ultra 2, Solaris 2.5.1 (anyone knows about a 2.5.1 binary?).
> 
> During compile-/linktime I get some messages
> 'warning: creation of object of this type may raise Storage_Error'
> from code like
> ---
>    type T_Polygon_XYZ (Max_Punkte: Natural := 1) is
>       record
>         Punkte : Natural   := Max_Punkte;  -- Anzahl der Polygonpunkte
>         X : T_Vector_Float(1..Max_Punkte) := (others => 0.0);
>         Y : T_Vector_Float(1..Max_Punkte) := (others => 0.0);
>         Z : T_Vector_Float(1..Max_Punkte) := (others => 0.0);
>       end record;
> 
> where
> 
>    type  T_Vector_Float   is array(integer range <>) of Float;

you are dealing with the classic "large length discriminant" problem.

you have indicated to the compiler that your record may have a
discriminant whose use is to determine the size of one of the record's
component arrays, and whose range bounds may be as large as Integer'LAST
(which on solaris for gnat3.09 is 2**31-1); therefore, it is technically
possible at run time for each of the component arrays to become that
large.  the compiler cannot know at the time you create the type that
you are never going to create an object:

	BigPolygon : T_Polygon_XYZ((2**31-1));

by doing this, in your case, you would be saying that you need storage
for three arrays each of 2 billion plus points.  this is almost
certainly more memory than your machine can handle.

this can also be a problem even if you don't declare a static variable
of type T_Polygon_XYZ.  if you had an access to T_Polygon_XYZ, and you
declared a new T_Polygon_XYZ of some size based on a run-time generated
value, you could end up causing the need for a huge amount of memory
without truly being able to detect the problem at compile time.

similarly, if T_Polygon_XYZ is used as the type of a parameter in some
subprogram, that subprogram has to be able to properly deal with the
parameter in the cases where the discriminant (and thus the array
lengths of the components) are as low as the default [i.e. 1] or as high
as the largest value of the type used for the discriminant range.

so, gnat (and just about any other ada compiler) gets smart, and when it
sees the original T_Polygon_XYZ, it recognizes that you've put a "really
big" type range in (i don't know what qualifies for "really big" in
gnat), and warns you of the potential problem.

a way to avoid this problem is to figure out a true (or at least
hardly-ever-to-be-met) maximum for the number of points in your polygon
... or whatever similar maximum there might be for other discriminant
types you declare, create a new type that uses those range bounds, and
use that type as your discriminant.

(alternatively, you could simply use variables that are 2D
unconstrained  arrays, or an array whose array components are
unconstrained arrays.  not every case of arrays using length
discriminants can be solved this way, obviously; it's just always best
to use the proper tool to do the job where possible, and
length-discriminanted records whose sole components are arrays is
perhaps a bit of overkill.)

> At runtime my (pure ADA) executables do what they are supposed to but
> at exit-time I get:
> 
> raised STORAGE_ERROR
> 
> and have to quit the program with ^C. gdb says:
> 
> Program received signal SIGBUS, Bus error.
> 0x10debc in _fini ()
> (gdb) bt
> #0  0x10debc in _fini ()
> #1  0xef69784c in _exithandle ()
> #2  0xef6f4174 in exit ()
> 
> Funny is the following: some (not all) of my executables terminate
> correctly
> when called from the directory they are located in but raise the above
> storage
> error when called from elsewhere (e.g. ../exename).

only guessing here, but because generally part of what happens when
leaving scope is re-claiming memory allocated to variables declared
within that stack frame, you may be running into a case where a huge
chunk of memory is getting set aside for the variable object of that
polygon type.  your run-time environment (i.e. environment variables,
arguments, etc.) may be just different enough that the cleanup works
okay in the one instance but not the other.  as i said, though, that is
just a w.a.g. (well...not *just*; knowing this group, it also becomes by
default an effort to bait someone who might really know an answer into
telling me i'm wrong and thereby giving you a more definitive answer...)

--Kirk Beitz
--johndoe@world.std.com






  reply	other threads:[~1997-06-24  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-06-23  0:00 Help with gnat storage error Myriam Witt
1997-06-24  0:00 ` Kirk Beitz [this message]
1997-06-24  0:00 ` Stephen Leake
1997-06-25  0:00   ` Peter Hermann
1997-06-26  0:00 ` Myriam Witt
1997-06-28  0:00 ` Robert Dewar
replies disabled

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