From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bc87a0d17d684f50 X-Google-Attributes: gid103376,public From: Kirk Beitz Subject: Re: Help with gnat storage error Date: 1997/06/24 Message-ID: <33AF98EB.73C2@world.std.com>#1/1 X-Deja-AN: 252648727 References: <5olggu$dcg$1@cdserv.rzg.mpg.de> To: kroemer@iabg.de Organization: Road Runner Reply-To: johndoe@world.std.com Newsgroups: comp.lang.ada Date: 1997-06-24T00:00:00+00:00 List-Id: 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