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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,9b7d3a51d0d8b6ee X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!news2.google.com!news.glorb.com!wn11feed!worldnet.att.net!bgtnsc04-news.ops.worldnet.att.net.POSTED!53ab2750!not-for-mail Newsgroups: comp.lang.ada From: anon@anon.org (anon) Subject: Re: Extending discriminant types Reply-To: no to spamers (No@email.given.org) References: <20081115101632.5f98c596@cube.tz.axivion.com> X-Newsreader: IBM NewsReader/2 2.0 Message-ID: Date: Thu, 20 Nov 2008 07:21:42 GMT NNTP-Posting-Host: 12.64.114.157 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc04-news.ops.worldnet.att.net 1227165702 12.64.114.157 (Thu, 20 Nov 2008 07:21:42 GMT) NNTP-Posting-Date: Thu, 20 Nov 2008 07:21:42 GMT Organization: AT&T Worldnet Xref: g2news1.google.com comp.lang.ada:2703 Date: 2008-11-20T07:21:42+00:00 List-Id: Since, the orginal post suggest that the poster was using GNAT Ada 95 compiler. Because the poster states that he can compiler the code. So, I used Gnat 3.15p using Ada 95 specs. Plus, the RM does not limited the "Base" attribute to only Scalar Types. Any defined type can use the "Base" attribute. Then you also have RM 2005 3.8.1 (17). -- -- This specification was found on Ada-auth.org web site. -- package U is type T is tagged private ; function "=" ( Left, Right : T'Base ) return Boolean ; private type T is tagged null record ; end U ; -- -- Dummy body package to comply with the specification package. -- package body U is function "=" ( Left, Right : T'Base ) return Boolean is begin return False ; end ; end U ; the previous code is valid in Ada 95 but will not compile using GNAT Ada 2005 (2007 or 2008 versions). And since a few here, like the "wiki" web sites: From: http://en.wikibooks.org/wiki/Ada_Programming/Types Under the section "Defining new types and subtypes". The page defines that for all T, "there is also a base type called T'Base, which encompasses all values of T." And under section "Base type" it says "In Ada, all types are anonymous and only subtypes may be named. There is a special subtype of the anonymous type, called the base type, which is nameable with the 'Base attribute. The base type comprises all values of the first subtypes." That states that the "Base" attribute not only included in all Scalar Types but all defined types as well. Which means that the Non Scalar defined "Access" type has a special subtype aka "Base" attribute that can be used. Plus, the concept of using the 'Base attribute and the 'Class attribute are the a part of the core of "Object-oriented" programming in Ada 95. With the "with record" part indicates the extension to the base type. But without this design it defect the purpose of some "Object-oriented" programming. There must be a base type for all types as well as all objects. So, either the definition of the "Base" attribute has been altered or limited by GNAT in the Ada 2005 specification. Or the GNAT Ada Pro 6.01 and GNAT Ada 2007 and 2008 now contains an error for the "Base" attribute. Now, back to the example! The type "Child" is defined in the following statement: type Child is new KBase (B) with null record; And the "Child" type is constrained by the record "KBase (B)" but the "Base" type or unconstrained subtype of type "Child" is the complete range of values, that is, a set comprising of a KBase(A) record and a KBase(B) record. So the statement Var1 : Base_Access := new Child'Base(K => B); used with the statement type Base_Access is access all KBase'Class; is legal because the statement generates an access value that has a Base type ("Base" attribute) value that is within the range of values of all Base_Access values. A variant define as "K => A" is illegal only during runtime when the value is assigned to the Var1 variable which is limited to a Base_Access that has a "KBase (B)" define by the type "Child". In , anon@anon.org (anon) writes: > >-- Your talking about "Variant Parts and Discrete Choices" (RM 3.8.1) >-- which is validated during runtine, if the variable is reference. >-- >-- Now with a smart compiler it could detect the error, but the >-- compiler in GNAT is not that smart. > >procedure t is > > -- Change "Base" to "KBase" to prevent confusion with predefine > -- Attribute 'Base, which als works. > > type Kind is (A, B); > > type KBase (K : Kind) is abstract tagged record > case K is > when A => null; > when B => Dummy : Natural; > end case; > end record; > > type Base_Access is access all KBase'Class; > > -- type "Child" is bound to KBase ( K => B ) so any reference > -- of "Child" to ( K => A ) should cause an error condition > -- but this only happens during runtime. > > type Child is new KBase (B) with null record; > > > -- Var2 is in error and should cause a Constaint_Error > -- once referenced. > > Var : Base_Access := new Child ; > Var0 : Base_Access := new Child'(K => B, Dummy => 5); > Var1 : Base_Access := new Child'Base(K => B); -- Just for Adam, this works > > Var2 : Base_Access := new Child'Base(K => A); > > >begin -- t > > Var.Dummy := 2 ; > Var0.Dummy := 4 ; > Var1.Dummy := 8 ; -- Just for Adam, this works > > -- Uncommenting the following line will result in a Constraint_Error > -- during runtine. But until Var2 is reference the validation of > -- type is not performed. > >-- Var2.Dummy := 16 ; > >end t ; > > > >In <20081115101632.5f98c596@cube.tz.axivion.com>, Stefan Bellon writes: >>Hi, >> >>I stumbled across some behaviour when extending an unconstrained >>discriminant type while providing the constraint when extending. Assume >>the following code: >> >> type Kind is (A, B); >> >> type Base (K : Kind) is abstract tagged record >> case K is >> when A => null; >> when B => Dummy : Natural; >> end case; >> end record; >> >> type Base_Access is access all Base'Class; >> >> type Child is new Base (B) with null record; >> >>In this case I would have thought that type Child is now constrained to >>Kind B and no object of type Child with Kind A can be created. >> >>However, the following compiles (with GNAT) and does not throw an >>exception at runtime: >> >> Var : Base_Access := new Child'(K => A); >> >>Am I misunderstanding the Ada semantics? If so, is there a way to >>achieve what I'm trying, i.e. that I can determine the Kind while >>extending and not change it when creating objects? >> >>Greetings, >>Stefan >> >