comp.lang.ada
 help / color / mirror / Atom feed
* 'Valid, subtypes and constraint checking
@ 2003-09-26 11:41 Peter Amey
  2003-09-26 13:13 ` Jean-Pierre Rosen
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Peter Amey @ 2003-09-26 11:41 UTC (permalink / raw)


Some guidance please to reduce the slight panic I am suffering from.

When reading in values from an external device it is important to check 
that the value read is a valid representation for its type.  The read 
values are also considered volatile so each read returns a potentially 
different value.

I have alsways believed the way to do this is:

ExternalPort : T;
Temp  : T;    -- note same SUBtype as the port
...
Temp := ExternalPort; -- no checks generated because same subtype
if Temp'Valid then
   -- we can use value safely
else
   -- handle error safely
end if;

I have also assumed that applying 'Valid to the volatile value 
(ExternalPort) is pointless because, even if the check passes, any 
subsequent use of ExternalPort may return a different (perhaps invalid) 
value.

My confidence has now been shaken by a test case for a compiler, as yet 
unnamed, which raises constraint error for the initial assignment of an 
invalid value in ExternalPort to Temp.  Is this correct behaviour?  If 
it _is_ correct, how can you ever validate external volatile data?

(Horrible strawman solution: do an unchecked conversion of External_Port 
into Temp and then do the validity check).

Thoughts?



Peter




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

* Re: 'Valid, subtypes and constraint checking
  2003-09-26 11:41 'Valid, subtypes and constraint checking Peter Amey
@ 2003-09-26 13:13 ` Jean-Pierre Rosen
  2003-09-26 18:18 ` Jeffrey Carter
  2003-09-27  1:30 ` Robert I. Eachus
  2 siblings, 0 replies; 10+ messages in thread
From: Jean-Pierre Rosen @ 2003-09-26 13:13 UTC (permalink / raw)


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


"Peter Amey" <peter.amey@praxis-cs.co.uk> a �crit dans le message de news:bl18e1$6ot2h$1@ID-69815.news.uni-berlin.de...
> Some guidance please to reduce the slight panic I am suffering from.
>
> When reading in values from an external device it is important to check
> that the value read is a valid representation for its type.  The read
> values are also considered volatile so each read returns a potentially
> different value.
> [...]

> (Horrible strawman solution: do an unchecked conversion of External_Port
> into Temp and then do the validity check).
>
Not a horrible solution. You cannot assume your value is a T until you have checked
for it!
As long as all you know is that it is a set of bits, put it in a variable appropriate for
sets of bits. *After* validity checking, you can consider it a T. And Unchecked_Conversion
is the appropriate tool for changing the view on a give set of bits.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr





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

* Re: 'Valid, subtypes and constraint checking
  2003-09-26 11:41 'Valid, subtypes and constraint checking Peter Amey
  2003-09-26 13:13 ` Jean-Pierre Rosen
@ 2003-09-26 18:18 ` Jeffrey Carter
  2003-09-26 21:48   ` Chad R. Meiners
  2003-09-27  1:30 ` Robert I. Eachus
  2 siblings, 1 reply; 10+ messages in thread
From: Jeffrey Carter @ 2003-09-26 18:18 UTC (permalink / raw)


Peter Amey wrote:

> ExternalPort : T;
> Temp  : T;    -- note same SUBtype as the port
> ...
> Temp := ExternalPort; -- no checks generated because same subtype
> if Temp'Valid then
>   -- we can use value safely
> else
>   -- handle error safely
> end if;

If External_Port can take on values not in T, then it should not be 
considered of subtype T. For example

subtype T is Unsigned_8 range 2#0000_0000# .. 2#0000_1111#;

External_Port : Unsigned_8;
for External_Port'Address use ...;
pragma Volatile (External_Port);

Temp_8 : Unsigned_8;
Temp   : T;
...
Temp_8 := External_Port;

if Temp_8 not in T then
    raise An_Appropriate_Exception;
end i;f

'Valid is perhaps more appropriate for a value obtained from 
Unchecked_Conversion, or portions of the software where it has been 
necessary to turn of checking:

External_Port : T;
-- clauses
...
declare
    pragma Suppress ...;
begin
    Temp := External_Port;
end;

if not Temp'Valid then
    raise ...;
end if;

--  process Temp

-- 
Jeff Carter
"Death awaits you all, with nasty, big, pointy teeth!"
Monty Python & the Holy Grail
20




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

* Re: 'Valid, subtypes and constraint checking
  2003-09-26 18:18 ` Jeffrey Carter
@ 2003-09-26 21:48   ` Chad R. Meiners
  0 siblings, 0 replies; 10+ messages in thread
From: Chad R. Meiners @ 2003-09-26 21:48 UTC (permalink / raw)



"Jeffrey Carter" <spam@spam.com> wrote in message
news:Jp%cb.4210$RW4.2204@newsread4.news.pas.earthlink.net...
>> if Temp_8 not in T then
>     raise An_Appropriate_Exception;
> end i;f

Peter might want to avoid raising an exception, though. ;-)

-CRM





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

* Re: 'Valid, subtypes and constraint checking
  2003-09-26 11:41 'Valid, subtypes and constraint checking Peter Amey
  2003-09-26 13:13 ` Jean-Pierre Rosen
  2003-09-26 18:18 ` Jeffrey Carter
@ 2003-09-27  1:30 ` Robert I. Eachus
  2003-09-29  7:27   ` 'Valid, subtypes and constraint checking - Thanks Peter Amey
  2 siblings, 1 reply; 10+ messages in thread
From: Robert I. Eachus @ 2003-09-27  1:30 UTC (permalink / raw)


Peter Amey wrote:

> My confidence has now been shaken by a test case for a compiler, as yet 
> unnamed, which raises constraint error for the initial assignment of an 
> invalid value in ExternalPort to Temp.  Is this correct behaviour?  If 
> it _is_ correct, how can you ever validate external volatile data?
> 
> (Horrible strawman solution: do an unchecked conversion of External_Port 
> into Temp and then do the validity check).
> 
> Thoughts?

Define a type that matches any possible value of ExternalPort.  That is 
the type of ExternalPort, whatever else you may think. Call it 
Port_Type, for now. To convert it to your internal type, you may be able 
to do

function My_Convert is
     new Unchecked_Conversion(Port_Type, Internal_Type);

Temp := My_Convert(ExternalPort);

However, you may have to do:

Temp1: Port_Type;
Temp2: Internal_Type;

Temp1 := ExternalPort;
if Internal_Type'Valid(My_Convert(Temp1))
then Temp2 := My_Convert(Temp1);
end if;

Don't worry about the apparent calling of My_Convert twice.  For most 
conversions, instances of Unchecked_Conversion generate no code.  (The 
special cases include when the source is a slice or a packed record 
component, which certainly isn't happening here.)

It sounds like the type you are converting to is one where the compiler 
assures itself that all values are in range or correct in some way.  For 
example it could check that pointers are divisible by four for some 
hardware.  These are the cases where you need the second construction.

-- 
                                                     Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




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

* Re: 'Valid, subtypes and constraint checking - Thanks
  2003-09-27  1:30 ` Robert I. Eachus
@ 2003-09-29  7:27   ` Peter Amey
  2003-09-30  2:58     ` Robert I. Eachus
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Amey @ 2003-09-29  7:27 UTC (permalink / raw)




Robert I. Eachus wrote:
> Peter Amey wrote:
> [original problem snipped]

Thanks to all the responders.  The advice is consistent and useful.  In 
deference to Jean-Pierre, I withdraw the adjective "horrible" for the 
use of unchecked conversion!

Peter




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

* Re: 'Valid, subtypes and constraint checking - Thanks
  2003-09-29  7:27   ` 'Valid, subtypes and constraint checking - Thanks Peter Amey
@ 2003-09-30  2:58     ` Robert I. Eachus
  2003-09-30 12:45       ` Marin David Condic
  0 siblings, 1 reply; 10+ messages in thread
From: Robert I. Eachus @ 2003-09-30  2:58 UTC (permalink / raw)


Peter Amey wrote:

> Thanks to all the responders.  The advice is consistent and useful.  In 
> deference to Jean-Pierre, I withdraw the adjective "horrible" for the 
> use of unchecked conversion!

The right name for Unchecked_Conversion is 
It_is_the_programmer's_job_to_do_some_checking_on_this_Conversion.

But the apostrophe would have made it an attribute. ;-)

Seriously the right place to use Unchecked_Conversion is when you, the 
programmer need to do some type checking, and nowhere else.

For completeness, Unchecked_Deallocation should be 
Assume_that_there_are_no_other_valid_copies_of_this_access_value.

In both cases, the compiler is not promising the user it won't do any 
checking, or will free the memory pointed to by the access value. The 
purpose of these units is to allow the programmer to assert something to 
the compiler.

-- 
                                        Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




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

* Re: 'Valid, subtypes and constraint checking - Thanks
  2003-09-30  2:58     ` Robert I. Eachus
@ 2003-09-30 12:45       ` Marin David Condic
  2003-09-30 21:30         ` Robert I. Eachus
  0 siblings, 1 reply; 10+ messages in thread
From: Marin David Condic @ 2003-09-30 12:45 UTC (permalink / raw)


I might like it better if it actually *did* guarantee that it was going 
to return storage to some available storage pool. (Bumper Sticker 
Sighting: "Free the Mallocs!") As it stands now, I can write a data 
structure package that handles all your inserts and deletes and utilizes 
Unchecked_Deallocation rather than managing its own storage pool and end 
up with a memory leak in what would otherwise appear to be perfectly 
good code.

Perhaps in practice, most compilers have connected 
Unchecked_Deallocation to some OS "free" routine. I suppose it is the 
job of the vendor to document that and the job of the user to check that 
this is the case. It would just be nice to have the standard guarantee 
that it does this or at least provide a means to check that the 
Unchecked_Deallocation actually *did* reclaim the storage. That way, 
you'd know if you could count on it to do the job you'd expect it to do.

MDC


Robert I. Eachus wrote:
> In both cases, the compiler is not promising the user it won't do any 
> checking, or will free the memory pointed to by the access value. The 
> purpose of these units is to allow the programmer to assert something to 
> the compiler.
> 


-- 
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/NSFrames.htm

Send Replies To: m c o n d i c @ a c m . o r g

     "All reformers, however strict their social conscience,
      live in houses just as big as they can pay for."

          --Logan Pearsall Smith
======================================================================




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

* Re: 'Valid, subtypes and constraint checking - Thanks
  2003-09-30 12:45       ` Marin David Condic
@ 2003-09-30 21:30         ` Robert I. Eachus
  2003-10-01 12:44           ` Marin David Condic
  0 siblings, 1 reply; 10+ messages in thread
From: Robert I. Eachus @ 2003-09-30 21:30 UTC (permalink / raw)


Marin David Condic wrote:

> Perhaps in practice, most compilers have connected 
> Unchecked_Deallocation to some OS "free" routine. I suppose it is the 
> job of the vendor to document that and the job of the user to check that 
> this is the case. It would just be nice to have the standard guarantee 
> that it does this or at least provide a means to check that the 
> Unchecked_Deallocation actually *did* reclaim the storage. That way, 
> you'd know if you could count on it to do the job you'd expect it to do.

First, let me agree that compilers should try to document what they do 
in this area.  But it is harder than you might think.  For example, what 
if I try to free a task that is not yet terminated?  Perhaps the current 
task that is executing the call to Unchecked_Deallocation.  Right now a 
compiler can refuse to do anything in such a case, and in fact, is 
expected to do nothing.  (It can free SOME of the memory associated with 
the task, but not all.)

Or a different example.  If your compiler does provide a garbage 
collected heap, do you want Free to trump the garbage collector?  (This 
would mean that the only time Free did something was when the object was 
still accessable...ouch!

A better example is probably reference counted storage.  There you want 
   a call to Free to decrement the count by one, and release the storage 
if the count is equal to zero.

Or let's imagine a 64-bit address space on a virtual memory machine. 
There could be a clever implementation of the heap which keeps a list of 
  space that has been freed on pages that are currently non-resident. 
The memory manager could also decide to materialize a new page of memory 
for an allocation instead of paging in a page that has some free space, 
etc.  Reasonable implementation of a heap?  Sure.  Should an Ada 
compiler be allowed to use such a heap on a system that provides it?  Of 
course.
There are other cases, but I think you get the picture.  The reference 
manual is careful not to say too much.  Vendor documentation can and 
should be much more forthcoming.


-- 
                                         Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




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

* Re: 'Valid, subtypes and constraint checking - Thanks
  2003-09-30 21:30         ` Robert I. Eachus
@ 2003-10-01 12:44           ` Marin David Condic
  0 siblings, 0 replies; 10+ messages in thread
From: Marin David Condic @ 2003-10-01 12:44 UTC (permalink / raw)


O.K. From the perspective of the Standard, it may be undesirable to say 
too much or you stop someone from doing something useful in a given 
implementation environment. The down side of that, of course, is that 
you now have uncertain behavior - which rather defeats the purpose of 
having a standard, doesn't it?

If there were a "Marins_Unchecked_Deallocation ()" subprogram, it would 
most likely return a flag indicating success or a count of the number of 
bytes freed - or maybe both. I'd just like to know if my call to 
Unchecked_Deallocation did me any good or was I just wasting my time & 
creating a potential memory leak that I couldn't see because the code 
looked like it was doing what I thought it should be doing. My way, if 
an implementation can't or won't reclaim the storage, I know that this 
happened. The ARM way, you have no clue if its any good except if the 
vendor documented what it does (and you could find it in the document!) 
The ARM way could also lead to non-portability, but my way would at 
least give the programmer a shot at writing portable code.

MDC


Robert I. Eachus wrote:
> 
> First, let me agree that compilers should try to document what they do 
> in this area.  But it is harder than you might think.  For example, what 
> if I try to free a task that is not yet terminated?  Perhaps the current 
> task that is executing the call to Unchecked_Deallocation.  Right now a 
> compiler can refuse to do anything in such a case, and in fact, is 
> expected to do nothing.  (It can free SOME of the memory associated with 
> the task, but not all.)
> 
> Or a different example.  If your compiler does provide a garbage 
> collected heap, do you want Free to trump the garbage collector?  (This 
> would mean that the only time Free did something was when the object was 
> still accessable...ouch!
> 
> A better example is probably reference counted storage.  There you want 
>   a call to Free to decrement the count by one, and release the storage 
> if the count is equal to zero.
> 
> Or let's imagine a 64-bit address space on a virtual memory machine. 
> There could be a clever implementation of the heap which keeps a list of 
>  space that has been freed on pages that are currently non-resident. The 
> memory manager could also decide to materialize a new page of memory for 
> an allocation instead of paging in a page that has some free space, 
> etc.  Reasonable implementation of a heap?  Sure.  Should an Ada 
> compiler be allowed to use such a heap on a system that provides it?  Of 
> course.
> There are other cases, but I think you get the picture.  The reference 
> manual is careful not to say too much.  Vendor documentation can and 
> should be much more forthcoming.
> 
> 


-- 
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/NSFrames.htm

Send Replies To: m c o n d i c @ a c m . o r g

     "All reformers, however strict their social conscience,
      live in houses just as big as they can pay for."

          --Logan Pearsall Smith
======================================================================




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

end of thread, other threads:[~2003-10-01 12:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-26 11:41 'Valid, subtypes and constraint checking Peter Amey
2003-09-26 13:13 ` Jean-Pierre Rosen
2003-09-26 18:18 ` Jeffrey Carter
2003-09-26 21:48   ` Chad R. Meiners
2003-09-27  1:30 ` Robert I. Eachus
2003-09-29  7:27   ` 'Valid, subtypes and constraint checking - Thanks Peter Amey
2003-09-30  2:58     ` Robert I. Eachus
2003-09-30 12:45       ` Marin David Condic
2003-09-30 21:30         ` Robert I. Eachus
2003-10-01 12:44           ` Marin David Condic

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