comp.lang.ada
 help / color / mirror / Atom feed
* When to do a constraint check and not ??
@ 2001-10-26  8:29 Per Sandberg
  2001-10-26 12:01 ` Peter Hend�n
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Per Sandberg @ 2001-10-26  8:29 UTC (permalink / raw)


Assume the folowing code:

procedue bla is
	b : boolean; --< B may contain any bit pattern at this point.

	procedure test( p : in out boolean ) is
	begin
		b := false;
	end test;

begin
	test(b); --<< Is the compiler allowed to insert a constraint check on b
here ??
end;

Is the answer that it is up to the wendor.
I did not get any clues from the LRM.

/Per Sandberg.



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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
@ 2001-10-26 12:01 ` Peter Hend�n
  2001-10-26 13:57 ` DuckE
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Peter Hend�n @ 2001-10-26 12:01 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]

"Per Sandberg" wrote:
> procedue bla is
> b : boolean; --< B may contain any bit pattern at this point.

> procedure test( p : in out boolean ) is
> begin
> b := false;
> end test;

> begin
> test(b); --<< Is the compiler allowed to insert a constraint check on b
> here ??
> end;

> Is the answer that it is up to the wendor.
> I did not get any clues from the LRM.

The main clues are in 3.3.1, 13.9.1 and H.1 of ARM. There are some
comments in the same sections of the AARM.

My interpretation: The compiler is allowed, but not required, to raise
Constraint_Error or Program_Error exactly at (before) the call to test
in your example.

I'd be happy to hear from anyone more knowledgable than me on this,
even if my Coding Rules would still be to require initialization of all
objects at the earliest possible place, ie. normally at declaration.

Regards,
Peter Hend�n

--
Peter Hend�n           http://www.algonet.se/~phenden
ICQ: 14672398
Teknisk Dokumentation AB          http://www.tdab.com






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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
  2001-10-26 12:01 ` Peter Hend�n
@ 2001-10-26 13:57 ` DuckE
  2001-10-26 14:18 ` Ted Dennison
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: DuckE @ 2001-10-26 13:57 UTC (permalink / raw)


I'm not sure about the "rules" but...
I used a tool to translate a bunch of Pascal code to Ada.  The tool turned
"var" parameters into "in out" parameters.  Your example illustrates the
problem with that mapping.

We went through the translated code and depending on which made more sense:
  either initialized the variable prior to the call:
  b : boolean := FALSE;
  or changed the mode of the procedure parameter to "out":
  procedure test( p : out boolean ) is

Without these changes both GNAT and ObjectAda raise exceptions.

SteveD

"Per Sandberg" <prsa@systems.saab.se> wrote in message
news:3BD91EF8.EEB7EDBA@systems.saab.se...
> Assume the folowing code:
>
> procedue bla is
> b : boolean; --< B may contain any bit pattern at this point.
>
> procedure test( p : in out boolean ) is
> begin
> b := false;
> end test;
>
> begin
> test(b); --<< Is the compiler allowed to insert a constraint check on b
> here ??
> end;
>
> Is the answer that it is up to the wendor.
> I did not get any clues from the LRM.
>
> /Per Sandberg.





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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
  2001-10-26 12:01 ` Peter Hend�n
  2001-10-26 13:57 ` DuckE
@ 2001-10-26 14:18 ` Ted Dennison
  2001-10-26 23:44 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ted Dennison @ 2001-10-26 14:18 UTC (permalink / raw)


In article <3BD91EF8.EEB7EDBA@systems.saab.se>, Per Sandberg says...
>
>Assume the folowing code:
>
>procedue bla is
>	b : boolean; --< B may contain any bit pattern at this point.
>
>	procedure test( p : in out boolean ) is
>	begin
>		b := false;
>	end test;
>
>begin
>	test(b); --<< Is the compiler allowed to insert a constraint check on b
>here ??
>end;

I don't see why it wouldn't be allowed to. It seems quite sensible to want to
verify the object before it is read. Reading the variable is what you are saying
will happen in your routine when you give the parameter a mode designator of
"in". 

In this example, there's really no reason why your parameter needs to be "in
out". Even if you had extra code in there that, say, tried to read "b" later on
in "test", you could have used mode "out". The only reason you could possibly
need "in out" is if you might want to read the value inside of "test" *before*
test writes to it. That would clearly only be valid if a valid value is passed
in, and in that case you definitely *want* the constraint check (and probably
want it where they placed it).

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

No trees were killed in the sending of this message. 
However a large number of electrons were terribly inconvenienced.



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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
                   ` (2 preceding siblings ...)
  2001-10-26 14:18 ` Ted Dennison
@ 2001-10-26 23:44 ` Jeffrey Carter
  2001-11-01 17:54 ` Tucker Taft
  2001-11-05 10:02 ` Peter Amey
  5 siblings, 0 replies; 8+ messages in thread
From: Jeffrey Carter @ 2001-10-26 23:44 UTC (permalink / raw)


Per Sandberg wrote:
> 
> Assume the folowing code:
> 
> procedue bla is
>         b : boolean; --< B may contain any bit pattern at this point.
> 
>         procedure test( p : in out boolean ) is
>         begin
>                 b := false;
>         end test;
> 
> begin
>         test(b); --<< Is the compiler allowed to insert a constraint check on b
> here ??
> end;
> 
> Is the answer that it is up to the wendor.
> I did not get any clues from the LRM.

The answer is that you have incorrectly specified the parameter mode of
P in Test. Since you do not reference the in value of P, the mode should
be out.

The compiler is required to insert a constraint check on B if it has a
subtype different from P, see 6.4.1(11). The subtype conversion and
assignment mentioned require a range check, just as if you did them
manually.

In this case B and P have the same subtype, so the compiler may assume
the value of B is valid for the subtype and eliminate the range check.
However, it is not required to eliminate the check, so the above appears
to be a bounded error.

-- 
Jeff Carter
"I wave my private parts at your aunties."
Monty Python & the Holy Grail



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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
                   ` (3 preceding siblings ...)
  2001-10-26 23:44 ` Jeffrey Carter
@ 2001-11-01 17:54 ` Tucker Taft
  2001-11-02  3:44   ` Robert Dewar
  2001-11-05 10:02 ` Peter Amey
  5 siblings, 1 reply; 8+ messages in thread
From: Tucker Taft @ 2001-11-01 17:54 UTC (permalink / raw)


Per Sandberg wrote:
> 
> Assume the folowing code:
> 
> procedue bla is
>         b : boolean; --< B may contain any bit pattern at this point.
> 
>         procedure test( p : in out boolean ) is
>         begin
>                 b := false;

I presume you meant to write: "p := false;" here.

>         end test;
> 
> begin
>         test(b); --<< Is the compiler allowed to insert a constraint check on b
> here ??

Yes, it may perform a constraint check here.  In Ada 95,
referencing an uninitialized variable is a "bounded error"
(whereas in Ada 83 it was "erroneous").  This typically
means that an Ada 95 compiler won't "believe" the subtype
declaration of an object if it hasn't been initialized.
Hence, it will need to check its value against the
bounds of the subtype before it assigns it to an
object that it *does* believe is in range.  Certainly
all compilers will want to believe that "in" and "in out"
parameters are in range, so the (implicit) assignment
from b to the formal parameter p when the function is
called will need to ensure the value is in range.
If it happens to have "stack junk" in it which puts it
outside the typical 0..1 range used for booleans, then
you will get a constraint_error raised here.

So unless a compiler otherwise ensures that "b" is in
range, it will want to perform a constraint check
when it is passed to "test."  As others have
suggested, if you don't want a constraint check
there, either initialize b, or make "p" into an "out"
parameter rather than "in out".

> end;
> 
> Is the answer that it is up to the wendor.
> I did not get any clues from the LRM.

It is up to the vendor in some sense, but the
fact that referencing an uninitialized variable
is only a "bounded error" makes it quite
likely that a check will be performed at this
point to avoid having an uninitialized variable
"poison" all IN and IN OUT parameters.

> 
> /Per Sandberg.

-- 
-Tucker Taft   stt@avercom.net   http://www.avercom.net
Chief Technology Officer, AverCom Corporation (A Titan Company) 
Bedford, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/~stt)



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

* Re: When to do a constraint check and not ??
  2001-11-01 17:54 ` Tucker Taft
@ 2001-11-02  3:44   ` Robert Dewar
  0 siblings, 0 replies; 8+ messages in thread
From: Robert Dewar @ 2001-11-02  3:44 UTC (permalink / raw)


Tucker Taft <stt@avercom.net> wrote in message news:<3BE18C46.1AB713B4@avercom.net>...
> Certainly
> all compilers will want to believe that "in" and "in out"
> parameters are in range, so the (implicit) assignment
> from b to the formal parameter p when the function is
> called will need to ensure the value is in range.
> If it happens to have "stack junk" in it which puts it
> outside the typical 0..1 range used for booleans, then
> you will get a constraint_error raised here.

This is incorrect, it simply describes one possible implementation of
the RM rules, there is no specific requirement in the RM that the
range check be performed here. Different compilers may (and do) take
different
viewpoints on when to insert validity checks (to meet
the RM requirement that invalid data not cause erroneous
execution in most cases).
 
In GNAT Pro, a new switch -gnatV allows detailed control over when
validity checks occur, and can be used to force
validity checks in many situations where they are not required. We
have found this to be a useful debugging aid.



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

* Re: When to do a constraint check and not ??
  2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
                   ` (4 preceding siblings ...)
  2001-11-01 17:54 ` Tucker Taft
@ 2001-11-05 10:02 ` Peter Amey
  5 siblings, 0 replies; 8+ messages in thread
From: Peter Amey @ 2001-11-05 10:02 UTC (permalink / raw)




Per Sandberg wrote:
> 
> Assume the folowing code:
> 
> procedue bla is
>         b : boolean; --< B may contain any bit pattern at this point.
> 
>         procedure test( p : in out boolean ) is
>         begin
>                 b := false;
>         end test;
> 
> begin
>         test(b); --<< Is the compiler allowed to insert a constraint check on b
> here ??
> end;
> 

FWIW, SPARK has an interesting take on this kind of problem.  Firstly,
SPARK annotations identify whether data is being imported to and/or
exported from a procedure; this must be consistent with parameter
modes.  So, based on its parameter mode in the above example, p of
procedure test would have to be both an import and an export.  This has
two consequences: (1) flow analysis will show that it isn't true (since
p is actually a pure export of test) and (2) a data flow error
(reference to uninitialized variable) will be raised at the call "test
(b)". 

If the correct annotation ("derives p from ;") is placed on test then
the rules of SPARK require the parameter mode to be made "out" and the
potential data flow error is removed.

Finally, SPARK protects from another problem in the example.  I assume
that the body of test is supposed to have the assignment "p := false"
rather than "b := false".  In Ada "b" is of course visible at this point
so the incorrect assignment is legal.  In SPARK, b is not visible unless
it is placed in a global annotation on test.  In this way we prevent
accidental holes in scope.

I know that this does not really answer the original question but I
couldn't help observing how often the difficult questions people raise
about odd corners of the Ada language turn out not to be issues at all
for SPARK.

regards



Peter

---------------------------------------------------------------------------   
      __         Peter Amey, Product Manager
        )                    Praxis Critical Systems Ltd
       /                     20, Manvers Street, Bath, BA1 1PX
      / 0        Tel: +44 (0)1225 466991
     (_/         Fax: +44 (0)1225 469006
                 http://www.praxis-cs.co.uk/

--------------------------------------------------------------------------



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

end of thread, other threads:[~2001-11-05 10:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-26  8:29 When to do a constraint check and not ?? Per Sandberg
2001-10-26 12:01 ` Peter Hend�n
2001-10-26 13:57 ` DuckE
2001-10-26 14:18 ` Ted Dennison
2001-10-26 23:44 ` Jeffrey Carter
2001-11-01 17:54 ` Tucker Taft
2001-11-02  3:44   ` Robert Dewar
2001-11-05 10:02 ` Peter Amey

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