* '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