comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: Ada 83 - avoiding unchecked conversions.
Date: 1996/12/11
Date: 1996-12-11T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023280001112962007210001@news.ni.net> (raw)
In-Reply-To: 32AED68A.48BE@aisf.com


In article <32AED68A.48BE@aisf.com>, "Chris Sparks (Mr. Ada)"
<sparks@AISF.COM> wrote:

>> function To_Integer_32 (Low, High : Integer_16)
>>    return Integer_32 is
>>
>>    type Integer_32_Record is
>>       record
>>          High_Order : Integer_16;
>>          Low_Order : Integer_16;
>>       end record;
>>
>>    for Integer_32_Record use
>>       record
>>          High_Order at 0 range 16 .. 32;
>
>You mean 31.
>
>>          Low_Order at 0 range 0 .. 15;
>
>You have to be careful here due to portability and bit ordering.

Someone else also pointed that out to me.  Does anyone know how to use the
Bit_Order attribute to make this portable?

Is this acceptable:

   for Integer_32_Record'Bit_Order use System.Low_Bit_First;

I'm confused because I'm not sure whether storage unit 0 refers to the most
significant bit or the least significant.  Does the Bit_Order attribute
only affect the interpretation of the bits, or of the storage unit too?


>  The_Record_Address : constant System.Address := The_Record'Address;
>  Result             : Integer_32;
>  for Result'Address use The_Record_Address;  -- New way
>--for Result      use at The_Record_Address;  -- Old way

I disagree with this "solution."  Overlays are never the way to go when
Unchecked_Conversion will do.


>> Some shops have the rule "Thou shalt not use Unchecked_Conversion."
>> But this is silly; use it when it makes sense.
>
>I concur.  Using Address Clauses would not be the right choice when
>a component within a structure has an initializing value (pointers,
>explicit initializations).

Yes, that it true, but it's still not the right solution here. 
Unchecked_Conversion is.

>> The proper place to use Unchecked_Conversion is at the interface
>> boundary of the sytem.  That seems to be the case for you, because you're
>> manipulating types whose size is known explicitly (16 and 32 bit integers).
>
>I don't know what this means.

"Close-to-metal" programming.  Think of a program as a system with definate
boundaries.  The boundaries for an embedded system, say, are the computer
itself (the OS or kernal, etc) and hardware devices over which you perform
external I/O.

When you do external device I/O, you have to know explicitly what the size
and representation is of all the data you exchange with the other
processor, because you both have to agree on a common format.  Ada excels
in this area because it allows you to state explicitly what the
representation of the data is by using size clauses and representation
clauses.

But knowing the representation of the data is only important at the
hardware level, ie "the interface boundary."  Internal to the software
there's a lot going on that doesn't depend on representation of the data,
so we want to practice some information hiding by letting the compiler
choose the representation.

For example,

   type T is range 1 .. 10;

I can use type T to do some calculations, but I certainly don't care if T
occupies 8, 16, or 32 bits.

It's a perfectly valid request to not use Unchecked_Conversion on types
like T, because I'm inside the software system.  But at the I/O layer, I
can't use types like T because I really do need to know T's representation
(because I have to send it to someone else outside the system).

So yes, I often really do need to use Unchecked_Conversion - at the
interface boundary.

Shops that make rules like "Don't use Unchecked_Conversion" mean well but
are confusing the internal and external aspects of the (software) system.

This confusion is also the reason why shops often say "Thou shalt not use
predefined types, because it's not portable."  This too is another silly
rule.  

It would be perfectly valid for such a rule at the interface layer, because
I have to know the representation of my types.  But internal to the
software system, I don't care, and using predefined types is just another
form of information hiding.

I've often seen code like this

   type Stack is limited private;

   type Length_Type is range ...
   for Lenght_Type'Size use 32;

   function Length (S : Stack) return Length_Type;
...
private
   type Stack is ...;
end;

This is pure overkill: who cares what the representation of the stack
length attribute is?  It's also wrong because they didn't use a
representation clause on the representation of type Stack.  Are you going
to send the stack object across an interface?  If not, then why do you care
what the representation is?

   function Length (S : Stack) return Natural;

is a perfectly good use of a predefined type.

Another egregious example is with array declarations:

   type T_Array is array (Integer_32 range <>) of T;

This is completely wrong: who cares what the representation of the array
index subtype is?  You never care about that even at the interface layer, 
because you don't actually send the array index across the interface - only
the components of the array.

Which is why using a subtype of Positive is often the best type for an
array index subtype.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
mheaney@ni.net
(818) 985-1271




  reply	other threads:[~1996-12-11  0:00 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <md5:8B831999BCF200C6E70994BDF6CC529F>
1996-12-11  0:00 ` Ada 83 - avoiding unchecked conversions Chris Sparks (Mr. Ada)
1996-12-11  0:00   ` Matthew Heaney [this message]
1996-12-12  0:00     ` Chris Brand
1996-12-13  0:00       ` Stephen Leake
1996-12-14  0:00         ` Robert A Duff
1996-12-14  0:00     ` BGaffney42
1996-12-11  0:00   ` Dewi Daniels
1996-12-12  0:00     ` Richard Kenner
1996-12-17  0:00       ` Eric Miller
1996-12-18  0:00         ` Robert Dewar
1996-12-18  0:00           ` Robert A Duff
1996-12-19  0:00           ` Keith Thompson
1996-12-26  0:00             ` Robert Dewar
1996-12-19  0:00   ` Robert I. Eachus
1996-11-27  0:00 Ensco Vendor
1996-11-27  0:00 ` Robert I. Eachus
1996-11-29  0:00 ` Robert Dewar
1996-12-01  0:00   ` Darel Cullen
1996-11-30  0:00     ` Robert Dewar
1996-12-11  0:00     ` Richard Riehle
1996-12-02  0:00 ` Ted Dennison
1996-12-10  0:00   ` Matthew Heaney
replies disabled

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