dlindsle@afit.af.mil (David T. Lindsley) (06/29/91)
I have a question about dynamic strings. I was looking at a package on simtel20 that did the following: subtype INDEX is natural range 0..100; type DYN_STRING (SIZE : INDEX := 0) is private; -- private -- type DYN_STRING (size : index := 0) is -- record -- DATA : string (1..size); -- end record; the second declaration had a note to the effect of "uncomment and use this if you've got a VALIDATED compiler". Now as far as I can tell, during elaboration, a declaration of the form S : DYN_STRING; will result in the attempt to allocate an array constrained to (1..0), which should raise an exception. At least, that's what it does under VAX Ada, but not on Verdix. (Both generate warnings.) It seems to me this has to be a bug in one of the compilers. My question is: whose? Should this, or should it not, raise an exception? (The LRM references weren't any help.) -- Dave Lindsley #24601# OPINIONS. MINE. (Nobody tells me dlindsle@blackbird.afit.af.mil anything anyway, so I can't possibly ?? lamroN eb yhW ?? be anybody's mouthpiece...)
howard@hulder.css.gov (Howard Turner) (06/29/91)
dlindsle@afit.af.mil (David T. Lindsley) writes: I have a question about dynamic strings. I was looking at a package on simtel20 that did the following: subtype INDEX is natural range 0..100; type DYN_STRING (SIZE : INDEX := 0) is private; -- private -- type DYN_STRING (size : index := 0) is -- record -- DATA : string (1..size); -- end record; the second declaration had a note to the effect of "uncomment and use this if you've got a VALIDATED compiler". Now as far as I can tell, during elaboration, a declaration of the form S : DYN_STRING; will result in the attempt to allocate an array constrained to (1..0), which should raise an exception. At least, that's what it does under VAX Ada, but not on Verdix. (Both generate warnings.) It seems to me this has to be a bug in one of the compilers. My question is: whose? Should this, or should it not, raise an exception? (The LRM references weren't any help.) Ahemm... While working on a recent project, I ran into much the same problem. One of the persons involved (Bob Smith, smith@prc.unisys.com) found the following and sent it to me. Bob set me right. Thanks Bob. Bob Smith (quite a while ago) writes: ... You might try reading LRM 3.6.1 paragraph 4: If any of the discrete ranges defines a null range, any array thus constrained is a null array, having no components. Then take a look at 3.5 paragraph 3: The range L .. R specifies the values from L to R inclusive if the relation L <= R is true. . . . A null range is a range for which the relation R < L is TRUE; no value belongs to a null range. ... While it does not explicitly mention strings, remember that the type string is defined as an array of characters. Hopes this helps Howard Turner SAIC 619.458.2654 howard@esosun.css.gov
jls@netcom.COM (Jim Showalter) (06/29/91)
dlindsle@afit.af.mil (David T. Lindsley) writes: >I have a question about dynamic strings. I was looking at a package >on simtel20 that did the following: > subtype INDEX is natural range 0..100; > type DYN_STRING (SIZE : INDEX := 0) is private; >-- private >-- type DYN_STRING (size : index := 0) is >-- record >-- DATA : string (1..size); >-- end record; >the second declaration had a note to the effect of "uncomment and use >this if you've got a VALIDATED compiler". >Now as far as I can tell, during elaboration, a declaration of the form > S : DYN_STRING; >will result in the attempt to allocate an array constrained to (1..0), >which should raise an exception. At least, that's what it does under >VAX Ada, but not on Verdix. (Both generate warnings.) No. If you declare S of type Dyn_String without specifying a value for the Size, what you get is a "mutable record". What this means is that you can come along later and assign a Dyn_String of any size to it, and it will work. The reason is that the default size of zero is NOT a discriminant, and so does not constrain the Data string to be of any particular size. A nifty compiler could play all sorts of games with mutable records to make them grow or shrink dynamically. As it is, a typical compiler simply allocates as much space as COULD be needed, and lets it go at that. In your example, this means 100 bytes or so of storage is allocated, regardless of whether you ultimately assign a two character string to S or a 73 character string to S. -- *** LIMITLESS SOFTWARE, Inc: Jim Showalter, jls@netcom.com, (408) 243-0630 **** *Proven solutions to software problems. Consulting and training on all aspects* *of software development. Management/process/methodology. Architecture/design/* *reuse. Quality/productivity. Risk reduction. EFFECTIVE OO usage. Ada/C++. *
rharwood@east.pima.edu (06/29/91)
In article <1991Jun28.193513.14271@afit.af.mil>, dlindsle@afit.af.mil (David T. Lindsley) writes: > [code example deleted for brevity... see same code below] > will result in the attempt to allocate an array constrained to (1..0), > which should raise an exception. At least, that's what it does under > VAX Ada, but not on Verdix. (Both generate warnings.) I compiled the following code on the VAX Ada compiler, ACS-LINKed it, and ran it, all without error: ================== Code Startes Here ================ procedure test_100 is -- This is your definition package: package his_definitions is subtype INDEX is natural range 0..100; type DYN_STRING (SIZE : INDEX := 0) is private; private type DYN_STRING (size : index := 0) is record DATA : string (1..size); end record; end his_definitions; use his_definitions; -- Your declaration here: S : DYN_STRING; begin null; end test_100;
mfeldman@seas.gwu.edu (Michael Feldman) (06/29/91)
In article <1991Jun29.003159.20278@netcom.COM> jls@netcom.COM (Jim Showalter) writes: > >No. If you declare S of type Dyn_String without specifying a value >for the Size, what you get is a "mutable record". What this means is >that you can come along later and assign a Dyn_String of any size to >it, and it will work. The reason is that the default size of zero >is NOT a discriminant, and so does not constrain the Data string to >be of any particular size. A nifty compiler could play all sorts of >games with mutable records to make them grow or shrink dynamically. >As it is, a typical compiler simply allocates as much space as COULD >be needed, and lets it go at that. In your example, this means 100 >bytes or so of storage is allocated, regardless of whether you ultimately >assign a two character string to S or a 73 character string to S. Hmmm. This is not quite correct, Jim, regarding space allocation. For example, Meridian allocates only a header block (dope vector, whatever) and acquires space dynamically when needed. TeleSoft allocates the maximum, which means that if the revord were declared as record (length: positive := whatever) stuff: string(1..length) end record; the runtime system would try to acquire positive'last bytes. Big trouble. On the other hand, allocating the maximum means that no reallocation ever has to be done for the life of the object. Moral: use the subtype system to keep the max length to a value that's realistic in your application. I was told once (but can't confirm) that Alsys uses a _linked_ allocation, starting out with a blocksize equal to the default value and getting more blocks as needed. Can anyone confirm this? The point of my writing this is that implementing a powerful structure often involves classical time/space tradeoffs: Meridian will use time to save space (by always reallocating); TeleSoft will use space to save time. Alsys is in between somewhere. The wise designer will understand this and use the best structures for the job, in this case by choosing a range for the discriminant that makes sense. This is one of the portability gotchas in using any powerful structure; the careless designer will probably get burned the worst. BTW: I haven't seen a compiler manual yet that didn't lay out the details of their data structures, just in case you're curious. Mike
jls@netcom.COM (Jim Showalter) (06/30/91)
>>A nifty compiler could play all sorts of >>games with mutable records to make them grow or shrink dynamically. >>As it is, a typical compiler simply allocates as much space as COULD ^^^^^^^ >>be needed, and lets it go at that. >Hmmm. This is not quite correct, Jim, regarding space allocation. For >example, [several counter-examples of compilers that do a nifty job of storage management for mutable records deleted] I'm probably suffering from obsolete data. Early compilers were notorious for using the largest size a mutable record could be in all cases. It looks as if the definition of "typical" compiler has changed for the better, and I've been buried so deep in the specifics of Rational's products for the past four years that I am out of touch with what the rest of the market has been up to. Gotta get out more... -- *** LIMITLESS SOFTWARE, Inc: Jim Showalter, jls@netcom.com, (408) 243-0630 **** *Proven solutions to software problems. Consulting and training on all aspects* *of software development. Management/process/methodology. Architecture/design/* *reuse. Quality/productivity. Risk reduction. EFFECTIVE OO usage. Ada/C++. *