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.7 required=5.0 tests=BAYES_00,INVALID_DATE, MSGID_SHORT,REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!attcan!uunet!software.org!collard From: collard@software.org (David Collard) Newsgroups: comp.lang.ada Subject: Re: constraint error question for language lawyers Keywords: unreasonable language restrictions frustrated programmer Message-ID: <1809@software.software.org> Date: 9 Nov 90 14:12:40 GMT References: <1802@software.software.org> Sender: news@software.org Reply-To: collard@software.org (David Collard) Organization: Software Productivity Consortium, Herndon, Virginia List-Id: In article <1802@software.software.org> blakemor@software.org (Alex Blakemore) writes: > OK, language lawyers of the world. > This one has stumped everyone I've asked locally, including several > people who have worked with Ada since there were compilers for it. > > Vax Ada 2.1 and two versions of Verdix (5.x and 6.0.3) all behave in the same > (unreasonable) manner - so there must be some obscure rule at work here. > Does anyone > a. know what that rule might be ? > b. profess to have a reasonable explanation for its existence. > > The Question: > Why does this procedure raise constraint error? > It happens on the second assignment to dummy, but > doesnt happen if dummy.len > 0 and appears to have > something to do with the function call "&" > > ---------------- cut here ----------------- > > with text_io; > use text_io; > > procedure bozo is > > type short is range 0 .. 10; > > type data is array (short range <>) of character; > > type var_text (len : short := 0) is > record > text : data (1 .. len); > end record; > > dummy : var_text; -- unconstrained > > procedure do_nothing (d : data) is > begin > null; > end do_nothing; > > begin > > put_line ("before"); > dummy := (len => 0, text => ""); > put_line ("during"); > dummy := (len => dummy.len + 1, > text => dummy.text & 'a'); > put_line ("after"); > > exception > > when constraint_error => > put_line ("constraint_error raised"); > > end bozo; > > ---------------- cut here ----------------- > > Here is the output: > > before > during > constraint_error raised > > -------------------------------------------------------------------- > Alex Blakemore CSNET: blakemore@software.org > Software Productivity Consortium > 2214 Rock Hill Road Herndon, VA 22070 (703) 742-7125 --This is really just another case of another weirdness about ada, which has --been discussed here before. It involves the bounds of an array cannot be --changed during an aggregate assignment, as shown below: procedure aggassign is type short is new integer range 0..100; type intarray is array(short range <>) of integer; type rec(a:short := 0) is record b : intarray(1..a); end record; x : rec; c : intarray(8..8) := (others => 0); d : intarray(1..1) := (others => 0); begin x := (a => 1, b => d); -- will NOT raise constraint error x := (a => 1, b => c); -- will raise constraint error end aggassign; --The reason your program is the same is because of LRM 4.5.3-5 which --states that during catenation, when one operand is an element rather --than an array, it is treated as if it were the same as an array with --its bounds being the lower bound of the subtype of the index of --the array. In your case this is zero. so your assignment is --equivalent to: -- -- dummy := (len => dummy.len + 1, -- text => dummy.text & (0 => 'a')); -- --which, as shown in the example above, will raise constraint error. -- --instead, you can do what you want by explicitly stating the bounds --of the array of one character as: -- -- dummy := (len => dummy.len + 1, -- text => dummy.text & (1 => 'a')); -- --which works just fine: with Text_IO; use Text_IO; procedure bozo is type short is range 0..10; type data is array(short range <>) of character; type var_test(len : short := 0) is record text : data(1..len); end record; dummy : var_test; begin put_line("before"); dummy := (len => 0, text => ""); put_line("during"); dummy := (len => dummy.len + 1, -- this WILL work text => dummy.text & (1 => 'a')); -- dummy := (len => dummy.len + 1, -- this WILL NOT work! -- text => dummy.text & 'a'); -- -- dummy := (len => dummy.len + 1, -- this is equivalent to the -- text => dummy.text & (0 => 'a')); -- last one and WILL NOT work! -- -- dummy := (len => dummy.len + 1, -- this WILL NOT work either! -- text => dummy.text & (5 => 'a')); put_line("after"); end bozo; -- ----------------------------------------------------------------------- D. Thor Collard Internet: collard@software.org Software Productivity Consortium UUNET: ...!uunet!software!collard 2214 Rock Hill Rd, Herndon VA 22070