news@planck.uucp (Usenet News) (07/26/90)
Why is it that implicit array type conversion does not apply to the following situation? I can't find anything in the RM that disallows this situation for implicit conversion. The compiler (Verdix Sun 4 Self, version 6.0.2(g)) gives the following warning for the assignment to B: warning: RM 3.6.1: bounds check will raise CONSTRAINT_ERROR at runtime It does raise the exception on execution. I sorta wanted to get some other views before I flag this to Verdix as a bug. Minor flame: Its real easy to miss some statement buried in the RM which clarifies these kinds of language lawyer issues. ------------------------ cut here ---------------------------------- procedure Strings is type STRING (Len : NATURAL) is record S : Standard.STRING(1..Len); end record; A : Standard.STRING(7..7); B : STRING(1); begin -- Strings A := "X"; B := (A'length, A); end Strings; Terry J. Westley Arvin/Calspan Advanced Technology Center P.O. Box 400, Buffalo, NY 14225 acsu.buffalo.edu!planck!hercules!westley
collard@software.org (David Collard) (07/27/90)
In article <1990Jul26.132742.3828@planck.uucp> acsu.buffalo.edu!planck!hercules!westley () writes: > Why is it that implicit array type conversion does not apply to the > following situation? I can't find anything in the RM that disallows > this situation for implicit conversion. > > procedure Strings is > > type STRING (Len : NATURAL) is > record > S : Standard.STRING(1..Len); > end record; > > A : Standard.STRING(7..7); > B : STRING(1); ^^^^^^^^^^^^^^ At this point B is constrained to Len = 1. Which is why a constraint error is raised later. > > begin -- Strings > > A := "X"; > B := (A'length, A); > > end Strings; > An aggregate assignment which overrides the discriminant of a record is only allowed if the discriminant has a default and the object is not constrained when it is declared, i.e type STRING(Len : Natural := 0) is record S : Standard.STRING(1..Len); end record; B : String; If you change your declaration to this, then the assignment will not raise a constraint error. HOWEVER it still will not work because when the discriminant does have a default and an object is declared using the default , then the compiler will try to allocate enough space for the maximum value for the discriminant (probably over 2 billion if Natural is 32 bits) which is 1) Too much memory 2) Is beyond the maximum length for a string on some machines. What will work is: type String_Index is range 0..100; type String(Len : String_Index := 0) is record S : Standard.String(1..Natural(Len)); end record; B : String; But note that if the range of String_Index is large, you may be using a lot more memory than is apparent. The discriminated record is not intended to support dynamic allocation of different sized objects. If you really want dynamic allocation then use an access type. Good Luck -- ----------------------------------------------------------------------- D. Thor Collard Internet: collard@software.org Software Productivity Consortium UUNET: ...!uunet!software!collard 2214 Rock Hill Rd, Herndon VA 22070
NCOHEN@IBM.COM ("Norman H. Cohen") (07/27/90)
Given the declarations type My_String (Len : Natural) is record S : String (1..Len); end record; A : String(7..7); B : My_String(1); Terry Westley questions the raising of Constraint_Error by the following statement: B := (A'Length, A); (I have changed the name of Westley's record type to avoid confusion.) The exception is raised not by the assignment-statement check that the value of the righthand side belongs to the subtype of the lefthand side, but by the evaluation of the aggregate. (The same thing would happen if the assignment to B were replaced by C := (A'Length, A) = My_String'(1, "X"); where C is of type Boolean.) RM 4.3.1(3) states: For the evaluation of a record aggregate, the expressions given in the component associations are evaluated in some order that is not defined by the language.... A check is made that the value of each subcomponent of the aggregate belongs to the subtype of this subcomponent. The exception CONSTRAINT_ERROR is raised if this check fails. In this case, the value of A belongs to subtype String(7 .. 7) (because that's how A is declared) but the subtype of the second component of the aggregate (deduced from the type declaration for My_String and the discriminant value given by the first component in the aggregate) is String(1 .. 1). There's nothing in the RM to suggest that an implicit subtype conversion takes place here. Such conversions are mentioned only in 5.2(3) and 5.2.1(1), and only for assignment statements in which the lefthand side is a variable of an array type. The only problem with the compiler is that its warning message ought to have cited 4.3.1(3) rather than 3.6.1. Norman H. Cohen
stt@inmet.inmet.com (07/27/90)
Re: Implicit array subtype conversion It turns out that in Ada 83, implicit array subtype conversion (aka "sliding") only takes place on array assignment, and array object initialization at declaration (see RM 5.2.1 and 3.2.1:16). It is easy to argue that sliding should be applicable in more circumstances (or less, if it makes no sense for the array type), but alas, the presence of sliding has been linked to the use of named-with-others array aggregates (see RM 4.3.1:6). Generally, where sliding is legal, named-with-others is illegal. Actually, it is quite possible to imagine a rule that would allow both to be legal in the same context, by simply stating that an array aggregate with an OTHERS choice always takes the bounds implied by the "applicable index constraint" even though sliding might have allowed for different bounds in the same context. Ada 9X will likely address this issue. S. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138
mfeldman@seas.gwu.edu (Michael Feldman) (07/28/90)
In article <1469@software.software.org> collard@software.org (David Collard) writes: >In article <1990Jul26.132742.3828@planck.uucp> acsu.buffalo.edu!planck!hercules!westley () writes: > > type STRING(Len : Natural := 0) is > record > S : Standard.STRING(1..Len); > end record; > > B : String; > >If you change your declaration to this, then the assignment will not >raise a constraint error. >HOWEVER it still will not work because when the discriminant does have >a default and an object is declared using the default , then the compiler >will try to allocate enough space for the maximum value for the discriminant >(probably over 2 billion if Natural is 32 bits) which is > 1) Too much memory > 2) Is beyond the maximum length for a string on some machines. Well, maybe. Actually it is implementation-dependent. TeleSoft indeed allocates for the maximum, so the space never needs to be reallocated. Meridian allocates only a header block, then allocates dynamically as much space as is needed. What can other readers report about their compilers? The above example shows VERY POOR use of the type system, since a string is not likely to grow to integer'last characters. The correction below is just the right approach. This is also a good example of how Ada, for better or worse, leaves most storage-management issues to the implementer. I think this is appropriate, by the way, but one has to realize that it is so. Often the implementation dependent surprises can be minimized by intelligent use of types, as in this case. >What will work is: > > type String_Index is range 0..100; > > type String(Len : String_Index := 0) is > record > S : Standard.String(1..Natural(Len)); > end record; > > B : String; > > >But note that if the range of String_Index is large, you may be using >a lot more memory than is apparent. > >The discriminated record is not intended to support dynamic allocation >of different sized objects. If you really want dynamic allocation then >use an access type. I'm not sure I agree with this. I think people should try to minimize their use of access types, though this is clearly a matter of taste which we shouldn't get religious about. Discriminated records and unconstrained arrays - and a number of other features - aid in reducing the amount of recourse to access types. Given the risks and storage management problems associated - in all languages - with pointers, I encourage the use of these language-provided pointer-avoidance schemes. There is no free lunch, as the time/space tradeoffs inherent in this example make quite clear, and of course there is still no substitute for common sense. --------------------------------------------------------------------------- Prof. Michael Feldman Department of Electrical Engineering and Computer Science The George Washington University Washington, DC 20052 +1-202-994-5253 mfeldman@seas.gwu.edu ---------------------------------------------------------------------------