comp.lang.ada
 help / color / mirror / Atom feed
* constraint error question for language lawyers
@ 1990-11-08 17:18 Alex Blakemore
  1990-11-09 14:12 ` David Collard
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Alex Blakemore @ 1990-11-08 17:18 UTC (permalink / raw)


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

^ permalink raw reply	[flat|nested] 6+ messages in thread
* constraint error question for language lawyers
@ 1990-11-09 14:36 "Norman H. Cohen"
  1990-11-30 16:02 ` James THIELE
  0 siblings, 1 reply; 6+ messages in thread
From: "Norman H. Cohen" @ 1990-11-09 14:36 UTC (permalink / raw)


Alex Blakemore asks why, given the declarations

  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

the statements

  Dummy := (Len => 0, Text => "");
  Dummy := (Len  => Dummy.Len + 1,
            Text => Dummy.Text & 'a');

raise Constraint_Error in the second assignment.

The surprise results from the fact that the catenation

   Dummy.Text & 'a'

(where Dummy.Text = "") has bounds of 0 .. 0.  Since the Text component
of type Var_Text has a lower bound of 1, the evaluation of the aggregate

   (Len  => Dummy.Len + 1,
    Text => Dummy.Text & 'a');

raises Constraint_Error.

Now to the legal citations.  RM 4.5.3(4), in discussing the result of a
catenation, states:

     The lower bound of this result is the lower bound of the left
     operand, unless the left operand is a null array, in which case
     the result of the catenation is the right operand.

In this case the left operand IS a null array, so the lower bound must
be that of the right operand.  In this case, however, the right operand
is not an array, but a character, so it has no lower bound.  The next
RM paragraph, 4.5.3(5), provides a rule to cover this case:

     If either operand is of the component type of an array type,
     the result of the catenation is given by the above rules, using
     in place of this operand an array having this operand as its only
     component and having the lower bound of the index subtype of the
     array type as its lower bound.

That is, 'a' is taken to be a shorthand for (Short'First => a).  Since
Short'First, or 0, is lower bound of the right operand, and since the
left operand is null, 0 is the lower bound of the catenation.

The actual raising of Constraint_Error is governed by RM 4.3.1(3),
which discusses the evaluation of record aggregates and states:

     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.

The only questionable rule in all of this is the rule that the value of
L&R, where L is a null array, is the value of R.  This seems natural at
first glance, but since Ada can have null arrays with different bounds
(0 .. -1, 1 .. 0, etc.) this conflicts with the usual rule (for L
nonnull) that the lower bound of the result is that of its left operand.
Alex Blakemore has provided an example where this nonuniform rule leads
to a nasty surprise.

I would modify the program as follows:  Add the subtype declaration

   subtype Positive_Short is Short range 1 .. Short'Last;

and use Positive_Short rather than Short as the index subtype of the
array type Data.  Since the Text component of the record type Var_Text
has a lower bound of one, this is more appropriate.  The Ada rules
tend to work more sensibly when the lower bound of an array is the lower
bound of its index subtype.  (In this case, 'a' would be taken as a
shorthand for (Positive_Short'First => 'a'), which has a lower bound of
1, so the catenation ""&'a' would have a lower bound of 1.)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~1990-11-30 16:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1990-11-08 17:18 constraint error question for language lawyers Alex Blakemore
1990-11-09 14:12 ` David Collard
1990-11-10  1:08 ` Charles H. Sampson
1990-11-17 10:12 ` Jean Pierre Rosen
  -- strict thread matches above, loose matches on Subject: below --
1990-11-09 14:36 "Norman H. Cohen"
1990-11-30 16:02 ` James THIELE

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox