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,45a9122ddf5fcf5 X-Google-Attributes: gid103376,public From: mazzanti@iei.pi.cnr.it (Franco Mazzanti) Subject: Re: Rules for Representation of Subtypes Date: 1996/10/02 Message-ID: #1/1 X-Deja-AN: 186699182 organization: IEI-CNR newsgroups: comp.lang.ada Date: 1996-10-02T00:00:00+00:00 List-Id: Larry wrote: > So can someone give an example of how Z'Valid _might_ be useful > after an unchecked conversion, as seems to be indicated by the > Reference Manual. Bob wrote: > If you unchecked_convert to a record (which is the usual case), then > you can usefully use 'Valid on the components. Be sure that the record > doesn't contain fancy stuff (details in the RM), but a record containing > scalar fields and constrained arrays will work. Then the following should work too ... generic type Source(<>) is limited private; type Target is (<>); function Checked_Scalar_Conversion (S:Source) return Target; with Unchecked_Conversion; function Checked_Scalar_Conversion (S : Source) return Target is type My_Rec is record Scalar : Target; end record; Tmp : My_Rec; My_Scalar: Target renames Tmp.Scalar; -- small trick: even if Tmp as a whole record becomes abnormal -- its scalar component can still be safely checked for validity -- without "using" the abnormal record object as a prefix. function Unchecked_Cvt is new Unchecked_Conversion (Source, My_Rec); begin if My_Rec'Size /= Source'Size or My_rec'Alignment /= Source'Alignment then raise Program_Error; end if; Tmp := Unchecked_Cvt (S); if My_Scalar'Valid then return My_Scalar; else raise Program_Error; end if; end Checked_Scalar_Conversion; At least, when I tried this with gnat it seemed to work. The following is a simple test program: with Unchecked_Conversion; with Checked_Scalar_Conversion; procedure Main is type T is access Integer; for T'Size use 32; type My_Scalar is new Integer range 1 .. Integer'Last; for My_Scalar'Size use 32; type My_Scalar2 is new Integer range 1 .. 10; for My_Scalar2'Size use 32; function Cvt is new Checked_Scalar_Conversion (T, My_Scalar); function Cvt is new Checked_Scalar_Conversion (T, My_Scalar2); function Cvt is new Unchecked_Conversion (T, Integer); Ptr : T := new Integer; I : Integer; N : My_Scalar; S : My_Scalar2; begin I := Cvt (Ptr); -- safely converts Text_Io.Put_Line (Integer'Image(I)); N := Cvt (Ptr); -- safely converts Text_Io.Put_Line (My_Scalar'Image(N)); S := Cvt (Ptr); -- raises Program_Error Text_Io.Put_Line (My_Scalar2'Image(S)); end Main; Actually, at a rigorous reading, the behavior has just changed from "erroneous" [RM 13.9.1(12)]" to "implementation-defined" [RM 13.9 (10, 11)]. And "implementation-defined" may still include the possibility of "erroneousness". But hopefully this not likely not to be the common case. Franco ---------------- Franco Mazzanti