From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Examining individual bytes of an integer Date: Mon, 15 Oct 2018 00:04:50 +0300 Organization: Tidorum Ltd Message-ID: References: <9d90fa3e-f800-4086-bf97-a65474a8140a@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Trace: individual.net lYyZv2K4JklvDq6cYP8BDwiD/U2gif0Y+waKZHcwuvSBToBilk Cancel-Lock: sha1:W+fizCvqP602pDeOJKx7Rk3ARtw= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 In-Reply-To: <9d90fa3e-f800-4086-bf97-a65474a8140a@googlegroups.com> Xref: reader02.eternal-september.org comp.lang.ada:54568 Date: 2018-10-15T00:04:50+03:00 List-Id: On 18-10-14 22:15 , Henrik Härkönen wrote: > I'd like to examine individual bytes of larger (in bit size) > integer type. In C would probably move byte pointer etc. Also > I'd need to have a way to construct the integer from individual bytes. > > Would this be "the Ada-way", the Unchecked_Conversion? It depends... for this particular case, I would say "no", for the endianness reasons that Jeffrey described. I would use the unsigned (modular) integer types in the predefined package Interfaces, such as Interfaces.Unsigned_32, which come with shift and rotate operations. For example, to extract the most significant octet of a 32-bit unsigned integer with value 435343, I would do (assuming "use Interfaces"): Z : Unsigned_32 := 435343; MS_Octet : constant Unsigned_32 := Shift_Right (Z, 24); To compose an unsigned 32-bit integer from the octets 77, 88, 99, and 22, listed in big-endian order, I would do: Z : Unsigned_32 := Shift_Left (77, 24) or Shift_Left (88, 16) or Shift_Left (99, 8) or 22; (If you need lots of such expressions, you could define an "&" operator to make that look like 77 & 88 & 99 & 22.) Using a record type with named octet components (and a Bit_Order clause) is ok, too, but then one needs some Unchecked_Conversions. If you really want to inspect the structure of integers in memory, address by address, then I think the only way is the same as in C: make an octet pointer to the memory representation and read octet by octet. (But note that the Storage_Unit for some strange machines may not be 8 bits.) (I have become very sensitive to endianness problems because my daily work involves writing Ada programs targeted to big-endian SPARC machines, but tested initially on little-endian PCs.) > ---8<--- > > procedure Main is > > type Byte is mod 256; > type Word is mod 2 ** 32; > > type E2 is array(1 .. 4) of Byte; > > Z: Word; > Y: E2; > > function Convert_To_E2 is new Ada.Unchecked_Conversion (Source => Word, > Target => E2); > > function Convert_To_Word is new Ada.Unchecked_Conversion (Source => E2, > Target => Word); > > begin > Y := Convert_To_E2(Word(435343)); > Z := Convert_To_Word(Y); > end Main; > > --->8--- > > At least that looks nice and neat, I could also use record with > assigned names to bytes if necessary. > > -Henrik > -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .