comp.lang.ada
 help / color / mirror / Atom feed
* integers of 1, 2, 4 bytes
@ 2014-06-15 17:57 hreba
  2014-06-15 18:43 ` Dmitry A. Kazakov
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: hreba @ 2014-06-15 17:57 UTC (permalink / raw)


Hi,

I want to translate some of my Oberon programs to Ada.

So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and 
LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful 
too. In Oberon one uses CHAR for that.

The most obvious translation for INTEGER would be

   type INT is range -32768 .. 32767;

(all platforms I have been working on use the two's complement).

My Ada book says that range checks are applied to constrained subtypes 
(like that one) but not to unconstrained subtypes, but but overflow 
checks are applied nevertheless. So I came up with

   type Int16 is range -32768 .. 32767;
   for Int16'Size use 16;
   type INT is new Int16'Base;

as a more efficient definition.

Now it seems the range specification doesn't matter any more and that I 
could equally write

   type Int16 is range -1 .. 1;
   for Int16'Size use 16;
   type INT is new Int16'Base;

Would you really define a 16 bit integer type this way?

And how about non-negative types? Would the following have the values
0 .. 255?

   type Nat8 is range 0..1;
   for Nat8'Size use 8;
   type BYTE is new Nat8'Base;
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
@ 2014-06-15 18:43 ` Dmitry A. Kazakov
  2014-06-15 20:52   ` hreba
  2014-06-15 19:07 ` Niklas Holsti
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Dmitry A. Kazakov @ 2014-06-15 18:43 UTC (permalink / raw)


On Sun, 15 Jun 2014 14:57:31 -0300, hreba wrote:

> So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and 
> LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful 
> too. In Oberon one uses CHAR for that.

[...]

See ARM B.2:

http://www.ada-auth.org/standards/12rm/html/RM-B-2.html

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
  2014-06-15 18:43 ` Dmitry A. Kazakov
@ 2014-06-15 19:07 ` Niklas Holsti
  2014-06-15 21:25   ` hreba
  2014-06-15 19:26 ` Stefan.Lucks
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Niklas Holsti @ 2014-06-15 19:07 UTC (permalink / raw)


On 14-06-15 20:57 , hreba wrote:
> Hi,
> 
> I want to translate some of my Oberon programs to Ada.

That should be quite feasible.

> So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and
> LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful
> too. In Oberon one uses CHAR for that.

Ehm... why do you need exact equivalents to Oberon built-in types? Do
you intend to "write Oberon code in Ada", or do you intend to write in
"Ada style"? Ada style in choosing and defining types is to start from
what the type should represent (= the problem space), not to start from
how many bits it should use (= the solution space).

Which aspects of the integer types are important to you? You should
think of at least these aspects:

1. The range of the values of the type. Ada allows more flexibility here
than Oberon, I believe.

2. The size in bits of each variable of the type. Is this really
important for you? Do your Oberon programs deal with hardware
interfaces, or call procedures from other languages (e.g. C) where one
must ensure matching parameter types and sizes?

3. Behaviour in case of computations that exceed the range of the type:
do you want silent wrap-around, or an exception? What happened in your
Oberon programs in such case, and do you want the same thing to happen
in the Ada version? (Sorry, I don't know how Oberon normally handles
overflow.)

4. Do you need "bitwise" operations on these integers, such as shifts,
rotates, and bitwise logical and/or/xor/not?

As an example, if I need an integer type for which I know a range
(aspect 1) and I want an exception if I exceed the range (aspect 3) then
I would use the basic Ada form,

  type My_Int is <low limit> .. <high limit>;

and I would let the compiler choose whatever number of bits it finds
convenient. However, I would check that all intermediate values in my
calculations with My_Int also fit in the range - that is, I would choose
a range large enough to hold all intermediate computation values.
Otherwise, an overflow error could happen in the computations, even if
the final result is in the range.

On the other hand, if I want silent wrap-around, I would use Ada's
"modular" integers. And if I want bitwise operations, I would choose a
suitable modular type from the library package Ada.Interfaces, which
defines shift and rotate operations.

> The most obvious translation for INTEGER would be
> 
>   type INT is range -32768 .. 32767;
> 
> (all platforms I have been working on use the two's complement).
> 
> My Ada book says that range checks are applied to constrained subtypes
> (like that one) but not to unconstrained subtypes, but but overflow
> checks are applied nevertheless. So I came up with
> 
>   type Int16 is range -32768 .. 32767;
>   for Int16'Size use 16;
>   type INT is new Int16'Base;
> 
> as a more efficient definition.

Depends what you want; this type INT should signal overflow, but there
may be values that silently exceed the Int16 constraints. Is that what
you want? If I had some logical reason to use the range -32768..32767, I
would want to know if my program exceeds it.

(For overflow checking, note that GNAT traditionally disables overflow
checks by default, and you must use the option -gnato to enable them.)

> Now it seems the range specification doesn't matter any more and that I
> could equally write
> 
>   type Int16 is range -1 .. 1;
>   for Int16'Size use 16;
>   type INT is new Int16'Base;

I don't think that the Size specification influences the compiler's
choice of Int16'Base, so the compiler could choose an 8-bit integer as
Int16'Base, and just not use the "extra" 8 bits that the Size
specification gives you.

> Would you really define a 16 bit integer type this way?

No, never.

> And how about non-negative types? Would the following have the values
> 0 .. 255?
> 
>   type Nat8 is range 0..1;
>   for Nat8'Size use 8;
>   type BYTE is new Nat8'Base;

No. Nat8 is an ordinary signed integer type, and therefore Nat8'Base has
a symmetric signed range (except for a possible extra most negative
number, -2**n in addition to -(2**n - 1). Nat8'Base could have the range
-128..127, for example.

If you want unsigned integers, and the size matters to you, use a
modular type, perhaps one of those in Ada.Interfaces.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
  2014-06-15 18:43 ` Dmitry A. Kazakov
  2014-06-15 19:07 ` Niklas Holsti
@ 2014-06-15 19:26 ` Stefan.Lucks
  2014-06-15 21:31   ` hreba
  2014-06-15 22:09 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Stefan.Lucks @ 2014-06-15 19:26 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2903 bytes --]

On Sun, 15 Jun 2014, hreba wrote:

> My Ada book says that range checks are applied to constrained subtypes 
> (like that one) but not to unconstrained subtypes, but but overflow checks 
> are applied nevertheless. So I came up with
>
>  type Int16 is range -32768 .. 32767;
>  for Int16'Size use 16;
>  type INT is new Int16'Base;

If you *want* to get rid of range checks, there are pragmas to disable 
them. (Not that I would consider this a good idea at all ...). And I am 
not a language lawyer, but I claim that the Ada compiler will perform 
exactly the same range checks for INT, as it does for Int16 (see below).

So please just use Int16 as defined in

type Int16 is range -32768 .. 32767;
for Int16'Size use 16;

and disable range checking when and where you really need aggressively 
optimized codes (e.g., in the innermost loop ...).

So why does Ada perform range checks for INT? The reason is that INT is 
not "unconstrained", but actually in the range INT'First .. INT'Last for 
some INT'First and INT'Last of the compilers choice. INT'First might be 
smaller than Int16'First, and INT'Last might exceed Int16'Last, but there 
are still ranges to be checked. And, given the Size attribute, there 
appears no choice for the compiler anyway: INT'FIRST=Int16'First and 
INT'Last=Int16'Last imply exactly the same range chekcs for INT as for 
Int16.

> as a more efficient definition.

If you have specific performance constraints, you should try to optimize 
specific subprograms or code fragments, e.g., by disabling range checks 
within the innermost loop or so.

> Now it seems the range specification doesn't matter any more and that I 
> could equally write
>
>  type Int16 is range -1 .. 1;
>  for Int16'Size use 16;
>  type INT is new Int16'Base;
>
> Would you really define a 16 bit integer type this way?

Firstly, this makes your program hard to read, so this is poor software 
engineering. Secondly, it does not do what you want it to do -- i.e., it 
does not omit the range checks. And finally, the Ada compiler has a great 
deal of freedom what Int16'Base actually is. While I find it hard to 
imagine that an Ada compiler for any target machine with 2-complement 
arithmetic would not set Int16'Base to the range -2**15 .. +2**15-1, the 
Ada compiler might still surprise you.

> And how about non-negative types? Would the following have the values
> 0 .. 255?

Now for non-negative integers, there are modular types, which actually 
support arithmetic operations without range checking:

   type Byte is mod 2**8;
   for Byte'Size use 8;

(And similar for 2- and 4-byte arithmetic ...)


------  I  love  the  taste  of  Cryptanalysis  in  the morning!  ------
     <http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
--Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--

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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 18:43 ` Dmitry A. Kazakov
@ 2014-06-15 20:52   ` hreba
  0 siblings, 0 replies; 14+ messages in thread
From: hreba @ 2014-06-15 20:52 UTC (permalink / raw)


On 06/15/2014 03:43 PM, Dmitry A. Kazakov wrote:
> On Sun, 15 Jun 2014 14:57:31 -0300, hreba wrote:
>
>> So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and
>> LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful
>> too. In Oberon one uses CHAR for that.
>
> [...]
>
> See ARM B.2:
>
> http://www.ada-auth.org/standards/12rm/html/RM-B-2.html
>

That is indeed the best imaginable case: don't need to do anything, 
someone has done it already.

Thanks a lot for the hint.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 19:07 ` Niklas Holsti
@ 2014-06-15 21:25   ` hreba
  2014-06-15 22:39     ` Georg Bauhaus
  2014-06-16  4:46     ` J-P. Rosen
  0 siblings, 2 replies; 14+ messages in thread
From: hreba @ 2014-06-15 21:25 UTC (permalink / raw)


On 06/15/2014 04:07 PM, Niklas Holsti wrote:
> On 14-06-15 20:57 , hreba wrote:
>> Hi,
>>
>> I want to translate some of my Oberon programs to Ada.
>
> That should be quite feasible.
>
>> So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and
>> LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful
>> too. In Oberon one uses CHAR for that.
>
> Ehm... why do you need exact equivalents to Oberon built-in types? Do
> you intend to "write Oberon code in Ada", or do you intend to write in
> "Ada style"? Ada style in choosing and defining types is to start from
> what the type should represent (= the problem space), not to start from
> how many bits it should use (= the solution space).
>
> Which aspects of the integer types are important to you? You should
> think of at least these aspects:
>
> 1. The range of the values of the type. Ada allows more flexibility here
> than Oberon, I believe.
>
> 2. The size in bits of each variable of the type. Is this really
> important for you? Do your Oberon programs deal with hardware
> interfaces, or call procedures from other languages (e.g. C) where one
> must ensure matching parameter types and sizes?
>
> 3. Behaviour in case of computations that exceed the range of the type:
> do you want silent wrap-around, or an exception? What happened in your
> Oberon programs in such case, and do you want the same thing to happen
> in the Ada version? (Sorry, I don't know how Oberon normally handles
> overflow.)
>
> 4. Do you need "bitwise" operations on these integers, such as shifts,
> rotates, and bitwise logical and/or/xor/not?
>
> As an example, if I need an integer type for which I know a range
> (aspect 1) and I want an exception if I exceed the range (aspect 3) then
> I would use the basic Ada form,
>
>    type My_Int is <low limit> .. <high limit>;
>
> and I would let the compiler choose whatever number of bits it finds
> convenient. However, I would check that all intermediate values in my
> calculations with My_Int also fit in the range - that is, I would choose
> a range large enough to hold all intermediate computation values.
> Otherwise, an overflow error could happen in the computations, even if
> the final result is in the range.
>
> On the other hand, if I want silent wrap-around, I would use Ada's
> "modular" integers. And if I want bitwise operations, I would choose a
> suitable modular type from the library package Ada.Interfaces, which
> defines shift and rotate operations.
>
>> The most obvious translation for INTEGER would be
>>
>>    type INT is range -32768 .. 32767;
>>
>> (all platforms I have been working on use the two's complement).
>>
>> My Ada book says that range checks are applied to constrained subtypes
>> (like that one) but not to unconstrained subtypes, but but overflow
>> checks are applied nevertheless. So I came up with
>>
>>    type Int16 is range -32768 .. 32767;
>>    for Int16'Size use 16;
>>    type INT is new Int16'Base;
>>
>> as a more efficient definition.
>
> Depends what you want; this type INT should signal overflow, but there
> may be values that silently exceed the Int16 constraints. Is that what
> you want? If I had some logical reason to use the range -32768..32767, I
> would want to know if my program exceeds it.
>
> (For overflow checking, note that GNAT traditionally disables overflow
> checks by default, and you must use the option -gnato to enable them.)
>
>> Now it seems the range specification doesn't matter any more and that I
>> could equally write
>>
>>    type Int16 is range -1 .. 1;
>>    for Int16'Size use 16;
>>    type INT is new Int16'Base;
>
> I don't think that the Size specification influences the compiler's
> choice of Int16'Base, so the compiler could choose an 8-bit integer as
> Int16'Base, and just not use the "extra" 8 bits that the Size
> specification gives you.
>
>> Would you really define a 16 bit integer type this way?
>
> No, never.
>
>> And how about non-negative types? Would the following have the values
>> 0 .. 255?
>>
>>    type Nat8 is range 0..1;
>>    for Nat8'Size use 8;
>>    type BYTE is new Nat8'Base;
>
> No. Nat8 is an ordinary signed integer type, and therefore Nat8'Base has
> a symmetric signed range (except for a possible extra most negative
> number, -2**n in addition to -(2**n - 1). Nat8'Base could have the range
> -128..127, for example.
>
> If you want unsigned integers, and the size matters to you, use a
> modular type, perhaps one of those in Ada.Interfaces.
>

All I want is:
1. Same behaviour of translated program and original
2. Avoid unnecessary range checks.

1. Same behaviour

I want do extend one of my programs and I want to switch from Oberon to 
Ada. So first of all I want to translate the existing part and I want it 
to behave as the original. So it would be Oberon style. In most cases 
the range doesn't matter really. One uses the default integer type (64 
or 32 bits on PCs in C or 16 in Oberon) even in cases where the values 
don't exceed, let's say, 25.

Then I want to extend the program using Ada _style_, not just language. 
And, during this process, and acquiring practice, revise the translated 
part.

2. Avoid unnecessary range checks.

 From what I read I had understood the following: Subtypes are always 
range checked, and in addition there are overflow checks. When my 
subtype boundaries are equal to the limits of the base type, one of the 
checks is redundant. I have nothing against checks and I don't have 
performance issues, I just wanted to avoid _unnecessary_ checks.

Thanks for your explanations, it is much clearer now.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 19:26 ` Stefan.Lucks
@ 2014-06-15 21:31   ` hreba
  2014-06-15 21:55     ` Niklas Holsti
  0 siblings, 1 reply; 14+ messages in thread
From: hreba @ 2014-06-15 21:31 UTC (permalink / raw)


On 06/15/2014 04:26 PM, Stefan.Lucks@uni-weimar.de wrote:
> On Sun, 15 Jun 2014, hreba wrote:
>
>> My Ada book says that range checks are applied to constrained subtypes
>> (like that one) but not to unconstrained subtypes, but but overflow
>> checks are applied nevertheless. So I came up with
>>
>>  type Int16 is range -32768 .. 32767;
>>  for Int16'Size use 16;
>>  type INT is new Int16'Base;
>
> If you *want* to get rid of range checks, there are pragmas to disable
> them. (Not that I would consider this a good idea at all ...). And I am
> not a language lawyer, but I claim that the Ada compiler will perform
> exactly the same range checks for INT, as it does for Int16 (see below).
>
> So please just use Int16 as defined in
>
> type Int16 is range -32768 .. 32767;
> for Int16'Size use 16;
>
> and disable range checking when and where you really need aggressively
> optimized codes (e.g., in the innermost loop ...).
>
> So why does Ada perform range checks for INT? The reason is that INT is
> not "unconstrained", but actually in the range INT'First .. INT'Last for
> some INT'First and INT'Last of the compilers choice. INT'First might be
> smaller than Int16'First, and INT'Last might exceed Int16'Last, but
> there are still ranges to be checked. And, given the Size attribute,
> there appears no choice for the compiler anyway: INT'FIRST=Int16'First
> and INT'Last=Int16'Last imply exactly the same range chekcs for INT as
> for Int16.
>
>> as a more efficient definition.
>
> If you have specific performance constraints, you should try to optimize
> specific subprograms or code fragments, e.g., by disabling range checks
> within the innermost loop or so.
>
>> Now it seems the range specification doesn't matter any more and that
>> I could equally write
>>
>>  type Int16 is range -1 .. 1;
>>  for Int16'Size use 16;
>>  type INT is new Int16'Base;
>>
>> Would you really define a 16 bit integer type this way?
>
> Firstly, this makes your program hard to read, so this is poor software
> engineering. Secondly, it does not do what you want it to do -- i.e., it
> does not omit the range checks. And finally, the Ada compiler has a
> great deal of freedom what Int16'Base actually is. While I find it hard
> to imagine that an Ada compiler for any target machine with 2-complement
> arithmetic would not set Int16'Base to the range -2**15 .. +2**15-1, the
> Ada compiler might still surprise you.
>
>> And how about non-negative types? Would the following have the values
>> 0 .. 255?
>
> Now for non-negative integers, there are modular types, which actually
> support arithmetic operations without range checking:
>
>    type Byte is mod 2**8;
>    for Byte'Size use 8;
>
> (And similar for 2- and 4-byte arithmetic ...)
>
>
> ------  I  love  the  taste  of  Cryptanalysis  in  the morning!  ------
>      <http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
> --Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--

In my response to Niklas' answer I explained in some more detail what I 
wanted. Now it is clear to me that my type definition does not do that.

Thanks for your comments about style and compiler freedom.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 21:31   ` hreba
@ 2014-06-15 21:55     ` Niklas Holsti
  0 siblings, 0 replies; 14+ messages in thread
From: Niklas Holsti @ 2014-06-15 21:55 UTC (permalink / raw)


On 14-06-16 00:31 , hreba wrote:
> On 06/15/2014 04:26 PM, Stefan.Lucks@uni-weimar.de wrote:
>> On Sun, 15 Jun 2014, hreba wrote:

   [snip]

>>> Now it seems the range specification doesn't matter any more and that
>>> I could equally write
>>>
>>>  type Int16 is range -1 .. 1;
>>>  for Int16'Size use 16;
>>>  type INT is new Int16'Base;
>>>
>>> Would you really define a 16 bit integer type this way?
>>
>> Firstly, this makes your program hard to read, so this is poor software
>> engineering. Secondly, it does not do what you want it to do -- i.e., it
>> does not omit the range checks. And finally, the Ada compiler has a
>> great deal of freedom what Int16'Base actually is. While I find it hard
>> to imagine that an Ada compiler for any target machine with 2-complement
>> arithmetic would not set Int16'Base to the range -2**15 .. +2**15-1, the
>> Ada compiler might still surprise you.

I tried this on Mac OS-X, x86_64, GNAT 4.5:

   with Ada.Text_IO; use  Ada.Text_IO;

   procedure Bases
   is
      type Int16 is range -1 .. 1;
      for Int16'Size use 16;
      type INT is new Int16'Base;
   begin
      Put_Line (INT'Image (INT'First) & " .. " & INT'Image (INT'Last));
   end Bases;

The result is:

-128 ..  127


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
                   ` (2 preceding siblings ...)
  2014-06-15 19:26 ` Stefan.Lucks
@ 2014-06-15 22:09 ` Jeffrey Carter
  2014-06-16 15:38 ` Adam Beneschan
  2014-06-16 17:27 ` gautier_niouzes
  5 siblings, 0 replies; 14+ messages in thread
From: Jeffrey Carter @ 2014-06-15 22:09 UTC (permalink / raw)


On 06/15/2014 10:57 AM, hreba wrote:
>
> My Ada book says that range checks are applied to constrained subtypes (like
> that one) but not to unconstrained subtypes, but but overflow checks are applied
> nevertheless. So I came up with
>
>    type Int16 is range -32768 .. 32767;
>    for Int16'Size use 16;
>    type INT is new Int16'Base;
>
> as a more efficient definition.

This is a (probably) failed attempt at premature optimization, and might not be 
what you want. Int is likely to be exactly the same as Int16; if it isn't, it's 
probably because Int16'Base is 32 bits.

So you should simply define the types you need in the most natural, readable way 
possible, and not worry about "efficiency" until such time as you are unable to 
meet your timing requirements. In Ada, "the most natural, readable way" usually 
means defining types based on the problem, not based on the predefined types 
that a compiler happens to implement.

-- 
Jeff Carter
"This trial is a travesty. It's a travesty of a mockery of a
sham of a mockery of a travesty of two mockeries of a sham. ...
Do you realize there's not a single homosexual on that jury?"
Bananas
27


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 21:25   ` hreba
@ 2014-06-15 22:39     ` Georg Bauhaus
  2014-06-16 13:37       ` AdaMagica
  2014-06-16  4:46     ` J-P. Rosen
  1 sibling, 1 reply; 14+ messages in thread
From: Georg Bauhaus @ 2014-06-15 22:39 UTC (permalink / raw)


On 15/06/14 23:25, hreba wrote:

> All I want is:
> 1. Same behaviour of translated program and original
> 2. Avoid unnecessary range checks.
>
> 1. Same behaviour
> 2. Avoid unnecessary range checks.

If absence of range checks is part of 1., then it seems
an idea to expressly state the intent by

- documenting the intent using pragma Suppress (LRM 11.5),

- asking the compiler to suppress range checks when it
   translates a unit.

The 'Size attribute will still be useful for 1., I think.



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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 21:25   ` hreba
  2014-06-15 22:39     ` Georg Bauhaus
@ 2014-06-16  4:46     ` J-P. Rosen
  1 sibling, 0 replies; 14+ messages in thread
From: J-P. Rosen @ 2014-06-16  4:46 UTC (permalink / raw)


Le 15/06/2014 23:25, hreba a écrit :
> All I want is:
> 1. Same behaviour of translated program and original
> 2. Avoid unnecessary range checks.
> 
[...]
> 
> 2. Avoid unnecessary range checks.
> 
> From what I read I had understood the following: Subtypes are always
> range checked, and in addition there are overflow checks. When my
> subtype boundaries are equal to the limits of the base type, one of the
> checks is redundant. I have nothing against checks and I don't have
> performance issues, I just wanted to avoid _unnecessary_ checks.
> 
The Ada model requires checks; however, if a check is unnecessary (i.e.
statically provable as never failing), the compiler is allowed to remove
it, and in practice Ada compilers are quite good at removing unnecessary
checks.

More generally, the design of Ada took great care at not preventing
optimization. So you should not worry about that kind of optimization,
and let the compiler do it for you.

And if you still have doubts, compile the same program with and without
checks, and compare the timings; in general you'll be surprised by how
small the difference is. That's precisely because the compiler removes
all /unnecessary/ checks. All that remains are the /necessary/ checks;
that's why in Ada, you generally keep the tests in the delivered version.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 22:39     ` Georg Bauhaus
@ 2014-06-16 13:37       ` AdaMagica
  0 siblings, 0 replies; 14+ messages in thread
From: AdaMagica @ 2014-06-16 13:37 UTC (permalink / raw)


On Monday, June 16, 2014 12:39:47 AM UTC+2, Georg Bauhaus wrote:
> - documenting the intent using pragma Suppress (LRM 11.5),
> - asking the compiler to suppress range checks when it
>    translates a unit.

Be careful!

Pragma Suppress will not necessarily remove the check, e.g. when the check comes for "free" (see RM 11.5, especially (29)).

If a suppressed would have failed, the program is erroneous. See the RM 1.1.5 what erroneous means.


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
                   ` (3 preceding siblings ...)
  2014-06-15 22:09 ` Jeffrey Carter
@ 2014-06-16 15:38 ` Adam Beneschan
  2014-06-16 17:27 ` gautier_niouzes
  5 siblings, 0 replies; 14+ messages in thread
From: Adam Beneschan @ 2014-06-16 15:38 UTC (permalink / raw)


On Sunday, June 15, 2014 10:57:31 AM UTC-7, hreba wrote:
> Hi,
> 
> I want to translate some of my Oberon programs to Ada.
> 
> So I need the Oberon types SHORTINT (1 byte), INTEGER (2 bytes) and 
> LONGINT (4 bytes). A type BYTE (1 byte, values 0..255) would be useful 
> too. In Oberon one uses CHAR for that.
> 
> The most obvious translation for INTEGER would be
> 
>    type INT is range -32768 .. 32767;
> 
> (all platforms I have been working on use the two's complement).
> 
> My Ada book says that range checks are applied to constrained subtypes 
> (like that one) but not to unconstrained subtypes, but but overflow 
> checks are applied nevertheless. So I came up with
> 
>    type Int16 is range -32768 .. 32767;
>    for Int16'Size use 16;
>    type INT is new Int16'Base;
> 
> as a more efficient definition.

You normally shouldn't care about the size.  The only times you should really care about the size are (1) this integer type will be part of a data structure whose layout *must* look a certain way because the data structure will be read/written to a file or a socket or something; (2) the data will be used by non-Ada code that expects it to be a certain size; (3) you have lots of data and limited memory, and you need to ensure that the size is as small as possible even if it means that it will take longer to work with the data.

Otherwise, you don't need to specify the size.  

    type Int is range -(2**15) .. 2**15-1;

will let the compiler know that the values won't be outside that range, and it can use the information to help decide what's more efficient.  Which may still be a 32-bit integer, on many processors.

                                  -- Adam


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

* Re: integers of 1, 2, 4 bytes
  2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
                   ` (4 preceding siblings ...)
  2014-06-16 15:38 ` Adam Beneschan
@ 2014-06-16 17:27 ` gautier_niouzes
  5 siblings, 0 replies; 14+ messages in thread
From: gautier_niouzes @ 2014-06-16 17:27 UTC (permalink / raw)


> I want to translate some of my Oberon programs to Ada.

An OT advice from the experience of a few translations Modula-2 to Ada (guessing Oberon is same as M2 on these points): be careful with the following:
- M2 is case-sensitive, Ada not
- Ada's parameter passing rules are different
- Ada has no WITH instruction; you deal with a "rename" declaration

A not-so-bad way is to use a M2-Pascal translator, then the p2ada translator.
Especially the WITH instruction is correctly and automatically translated by p2ada (because there is a quasi Pascal compiler under the hood).
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address


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

end of thread, other threads:[~2014-06-16 17:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-15 17:57 integers of 1, 2, 4 bytes hreba
2014-06-15 18:43 ` Dmitry A. Kazakov
2014-06-15 20:52   ` hreba
2014-06-15 19:07 ` Niklas Holsti
2014-06-15 21:25   ` hreba
2014-06-15 22:39     ` Georg Bauhaus
2014-06-16 13:37       ` AdaMagica
2014-06-16  4:46     ` J-P. Rosen
2014-06-15 19:26 ` Stefan.Lucks
2014-06-15 21:31   ` hreba
2014-06-15 21:55     ` Niklas Holsti
2014-06-15 22:09 ` Jeffrey Carter
2014-06-16 15:38 ` Adam Beneschan
2014-06-16 17:27 ` gautier_niouzes

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