comp.lang.ada
 help / color / mirror / Atom feed
From: "Samuel T. Harris" <sam_harris@hso.link.com>
Subject: Re: Size of 0..255 is not 8 bits?
Date: 1998/05/15
Date: 1998-05-15T00:00:00+00:00	[thread overview]
Message-ID: <355C574F.3BA43583@hso.link.com> (raw)
In-Reply-To: 355C19C8.5D3A4545@cl.cam.ac.uk


Markus Kuhn wrote:
> 
> Robert Dewar wrote:
> > It is indeed a bug in a compiler if a Size clause for an object does not
> > result in the object tkaing the indicated nnumber of bits. But perhaps
> > you had better post the EXACT code that leads you to that conclusion.
> 
> Ok, here comes the exact code and the execution result of what
> confuses me.
> 
> Environment: gnat-3.10p-i386-linux-bin
>              Linux kernel 2.0.29
>              libc.so.5.3.12.
> 
> ---------------------------------------------------------------------
> with Ada.Text_IO.Text_Streams, Ada.Text_IO, Ada.Integer_Text_IO;
> use  Ada.Text_IO.Text_Streams, Ada.Text_IO, Ada.Integer_Text_IO;
> 
> procedure Strange2 is
> 
>    type Value is range 0..255;
>    for Value'Size use 8;
> 
>    V: Value;
>    for V'Size use 8;
> 
> begin
>    for X in 1..5 loop
>       Value'Read(Stream(Standard_Input), V);
>       Put(Integer(V));
>       New_Line;
>    end loop;
> end Strange2;
> ---------------------------------------------------------------------
> $ echo "ABCDEFGHIJK" | ./strange2
>          65
>          67
>          69
>          71
>          73
> ---------------------------------------------------------------------
> PROBLEM: Although I have been very explicit about that I want V
> to be 8 bits large, and although GNAT generated no errors or
> warnings when compiling the above, Value'Read clearly eats 16-bit
> chunks per call, but stores only the first 8 bits, which I consider
> highly surprising.
> I would have expected to see either an output like
>          65
>          66
>          67
>          68
>          69
> or to get a compiler error message telling me that the "use 8"
> representation clause for "range 0..255" cannot be used.
> ---------------------------------------------------------------------

This really isn't a 'size issue. The size of V is 8 bits.
If the stream was reading 16 bits and shoving all of them into
variable V then I'd expect a constraint_error!

The ARM states in section 13.13.2
Stream-Oriented Attributes:

For every subtype S of a specific type T, the follow attributes
are defined.

S'Write    S'Write denotes a procedure witht he following
           specification:

           procedure S'Write (Stream : access
                              Ada.Streams.Root_Stream_Type'Class;
                              Item   : in T)

           S'Write writes the value of Item to Stream.

S'Read     S'Read denotes a procedure with the following
           specification:

           procedure S'Read (Stream : access
                             Ada.Streams.Root_Stream_Type'Class;
                             Item : out T)

           S'Read reads the value of Item from Stream.

It is vitally important to note that 'Read and 'Write DO NOT
operate on Items of subtype S, but on type T. In the above code,
Value is the first subtype S of a base type T. Because it is
a signed integer type, it must be reflexive around 0. This means
the base type T MUST larger than 8 bits. Indeed, most compilers
are limited to machine supported sizes (means byte sized things)
so the base type T is 16 bits which is the next largest available
supported signed integer type. The Read and Write operations are
all occuring on objects of type T (16 bits) and not type S (Value
which is 8 bits).

So the stream is reading 16 bits into an Item of type T
which is 16 bits. Since the variable V is used in the call,
I'd expect some sort of type conversion to accomodate
the actual representation of the variable. It appears GNAT
is simply fitting the lower 8 bits into the 8 bit sized
variable V. This is unexpected behavior. I expect such a
type conversion and assignment of the out varible to
raise a constraint error since the 16 bit values are
outside of the range of V.

> 
> This looks like a GNAT 3.10p bug to me. If I replace "range 0..255"
> with "mod 256", then everything works nicely.

Of course it does. Modulo types are unsigned. They do not reflect
about 0. The base type does not need to be larger to accomodate
the extra values. A mod 256 type fits naturally into 8-bits so
both type Value and its base type T are 8 bits. The 'Read and 'Write
operations still operation on items of the base type T, which is
of 8 bits so everything works as expected. This goes to show
modulo types are the preferred types to use for such representations.

> 
> Markus
> 
> --
> Markus G. Kuhn, Security Group, Computer Lab, Cambridge University, UK
> email: mkuhn at acm.org,  home page: <http://www.cl.cam.ac.uk/~mgk25/>

-- 
Samuel T. Harris, Principal Engineer
Raytheon Training Incorporated
"If you can make it, We can fake it!"




  reply	other threads:[~1998-05-15  0:00 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-05-14  0:00 Size of 0..255 is not 8 bits? Markus Kuhn
1998-05-13  0:00 ` Matthew Heaney
1998-05-14  0:00   ` Markus Kuhn
1998-05-14  0:00     ` Robert Dewar
1998-05-14  0:00       ` Simon Pilgrim
1998-05-15  0:00       ` Markus Kuhn
1998-05-15  0:00         ` Samuel T. Harris [this message]
1998-05-15  0:00           ` Tucker Taft
1998-05-15  0:00       ` Joe Gwinn
1998-05-16  0:00         ` Robert Dewar
1998-05-17  0:00           ` Joe Gwinn
1998-05-14  0:00     ` John McCabe
1998-05-14  0:00       ` Robert Dewar
1998-05-14  0:00   ` Tom Moran
1998-05-14  0:00   ` Robert Dewar
replies disabled

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