comp.lang.ada
 help / color / mirror / Atom feed
* Should exceeding the range of Integer wrap around a la C?
@ 2018-05-21 15:23 nrs5134
  2018-05-21 15:27 ` Jacob Sparre Andersen
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: nrs5134 @ 2018-05-21 15:23 UTC (permalink / raw)


Hi all,

I'm brand-new to Ada coming from a Fortran & Python background - just starting to write some trivial tutorial programs. I'm trying to understand the output of following program (copied from the "Lovelace" Ada95 tutorial):

-- compute.adb
-- Demonstrate a trivial procedure, with another nested inside.
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure Compute is
   
   procedure Double(Item : in out Integer) is
   begin -- procedure Double
      Item := Item * 2;
   end Double;
   
   X : Integer := 1; -- Local variable X of type Integer
   
begin -- procedure Compute
   loop 
      Put(X);
      New_Line;
      Double(X);
   end loop;
end Compute;

I expect this program to print powers of 2 until `X` exceeds the range of Integer. Instead, it seems to "wrap around" with the following (abbreviated) output:
          1
          2
          4
      [...]          
  268435456
  536870912
 1073741824
-2147483648
          0
          0
      [...]
          0

I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat make compute` with no further compiler flags. Are my expectations wrong, or is this incorrect behavior?

Cheers,
NS

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
@ 2018-05-21 15:27 ` Jacob Sparre Andersen
  2018-05-21 15:45 ` Anh Vo
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Jacob Sparre Andersen @ 2018-05-21 15:27 UTC (permalink / raw)


nrs5134@gmail.com writes:

> I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat
> make compute` with no further compiler flags. Are my expectations
> wrong, or is this incorrect behavior?

`gnat make` is not an Ada compiler without some flags added.  From one
of my project files:

   package Compiler is
      for Default_Switches ("Ada")
        use ("-fstack-check", --  Generate stack checking code (part of Ada)
             "-gnata",        --  Enable assertions            (part of Ada)
             "-gnato13",      --  Overflow checking            (part of Ada)
             "-gnatf",                      --  Full, verbose error messages
             "-gnatwa",                     --  All optional warnings
             "-gnatVa",                     --  All validity checks
             "-gnaty3abcdefhiklmnoOprstux", --  Style checks
             "-gnatwe",                     --  Treat warnings as errors
             "-gnat2012",                   --  Use Ada 2012
             "-Wall",                       --  All GCC warnings
             "-O2");                        --  Optimise (level 2/3)
   end Compiler;

Greetings,

Jacob
-- 
Photo of the day (RSS feed):
         http://billeder.sparre-andersen.dk/dagens/feed.rss2

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
  2018-05-21 15:27 ` Jacob Sparre Andersen
@ 2018-05-21 15:45 ` Anh Vo
  2018-05-21 16:46   ` Simon Wright
  2018-05-21 15:57 ` Lucretia
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: Anh Vo @ 2018-05-21 15:45 UTC (permalink / raw)


On Monday, May 21, 2018 at 8:23:21 AM UTC-7, nrs...@gmail.com wrote:
> Hi all,
> 
> I'm brand-new to Ada coming from a Fortran & Python background - just starting to write some trivial tutorial programs. I'm trying to understand the output of following program (copied from the "Lovelace" Ada95 tutorial):
> 
> -- compute.adb
> -- Demonstrate a trivial procedure, with another nested inside.
> with Ada.Text_IO, Ada.Integer_Text_IO;
> use Ada.Text_IO, Ada.Integer_Text_IO;
> 
> procedure Compute is
>    
>    procedure Double(Item : in out Integer) is
>    begin -- procedure Double
>       Item := Item * 2;
>    end Double;
>    
>    X : Integer := 1; -- Local variable X of type Integer
>    
> begin -- procedure Compute
>    loop 
>       Put(X);
>       New_Line;
>       Double(X);
>    end loop;
> end Compute;
> 
> I expect this program to print powers of 2 until `X` exceeds the range of Integer. Instead, it seems to "wrap around" with the following (abbreviated) output:
>           1
>           2
>           4
>       [...]          
>   268435456
>   536870912
>  1073741824
> -2147483648
>           0
>           0
>       [...]
>           0
> 
> I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat make compute` with no further compiler flags. Are my expectations wrong, or is this incorrect behavior?

A Constraint_Error must be raised. If not, it is a compiler bug.

Anh Vo

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
  2018-05-21 15:27 ` Jacob Sparre Andersen
  2018-05-21 15:45 ` Anh Vo
@ 2018-05-21 15:57 ` Lucretia
  2018-05-21 16:49   ` Simon Wright
  2018-05-21 19:11 ` Paul Rubin
  2018-05-21 20:43 ` nrs5134
  4 siblings, 1 reply; 16+ messages in thread
From: Lucretia @ 2018-05-21 15:57 UTC (permalink / raw)


On Monday, 21 May 2018 16:23:21 UTC+1, nrs...@gmail.com  wrote:
> I expect this program to print powers of 2 until `X` exceeds the range of Integer. Instead, it seems to "wrap around" with the following (abbreviated) 

> I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat make compute` with no further compiler flags. Are my expectations wrong, or is this incorrect behavior?

Your compiler is ancient, upgrade to to at least 6.4.0.

On my machine with 6.4.0, gnatmake compute, then I run it, I get this:

$ ./compute 
          1
          2
          4
          8
         16
         32
         64
        128
        256
        512
       1024
       2048
       4096
       8192
      16384
      32768
      65536
     131072
     262144
     524288
    1048576
    2097152
    4194304
    8388608
   16777216
   33554432
   67108864
  134217728
  268435456
  536870912
 1073741824

raised CONSTRAINT_ERROR : compute.adb:8 overflow check failed

I didn't even specify "-gnata -gnato -gnatE" to gnatmake as I normally would, you want those options BTW.

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:45 ` Anh Vo
@ 2018-05-21 16:46   ` Simon Wright
  2018-05-21 18:47     ` Anh Vo
  0 siblings, 1 reply; 16+ messages in thread
From: Simon Wright @ 2018-05-21 16:46 UTC (permalink / raw)


Anh Vo <anhvofrcaus@gmail.com> writes:

> On Monday, May 21, 2018 at 8:23:21 AM UTC-7, nrs...@gmail.com wrote:

>> I expect this program to print powers of 2 until `X` exceeds the
>> range of Integer. Instead, it seems to "wrap around" with the
>> following (abbreviated) output:
>>           1
>>           2
>>           4
>>       [...]          
>>   268435456
>>   536870912
>>  1073741824
>> -2147483648
>>           0
>>           0
>>       [...]
>>           0
>> 
>> I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat
>> make compute` with no further compiler flags. Are my expectations
>> wrong, or is this incorrect behavior?
>
> A Constraint_Error must be raised. If not, it is a compiler bug.

This isn't a bug, it's a feature of older GNATs; AdaCore thought that
checking for overflow of machine integers would be too inefficient. The
fact that (a) everyone puts -gnato in their options and (b) -gnato is
now the default indicate that that thought was wrong (or, at any rate,
became wrong a good while ago).


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:57 ` Lucretia
@ 2018-05-21 16:49   ` Simon Wright
  0 siblings, 0 replies; 16+ messages in thread
From: Simon Wright @ 2018-05-21 16:49 UTC (permalink / raw)


Lucretia <laguest9000@googlemail.com> writes:

> I didn't even specify "-gnata -gnato -gnatE" to gnatmake as I normally
> would, you want those options BTW.

You don't want -gnatE unless you really really want to work out a set of
elaboration pragmas rather than letting the builder do it for you.


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 16:46   ` Simon Wright
@ 2018-05-21 18:47     ` Anh Vo
  0 siblings, 0 replies; 16+ messages in thread
From: Anh Vo @ 2018-05-21 18:47 UTC (permalink / raw)


On Monday, May 21, 2018 at 9:46:30 AM UTC-7, Simon Wright wrote:
> Anh Vo <anhvofrcaus@gmail.com> writes:
> 
> > On Monday, May 21, 2018 at 8:23:21 AM UTC-7, nrs...@gmail.com wrote:
> 
> >> I expect this program to print powers of 2 until `X` exceeds the
> >> range of Integer. Instead, it seems to "wrap around" with the
> >> following (abbreviated) output:
> >>           1
> >>           2
> >>           4
> >>       [...]          
> >>   268435456
> >>   536870912
> >>  1073741824
> >> -2147483648
> >>           0
> >>           0
> >>       [...]
> >>           0
> >> 
> >> I am compiling with GNAT 4.9.2 on a Debian Linux system using `gnat
> >> make compute` with no further compiler flags. Are my expectations
> >> wrong, or is this incorrect behavior?
> >
> > A Constraint_Error must be raised. If not, it is a compiler bug.
> 
> This isn't a bug, it's a feature of older GNATs; AdaCore thought that
> checking for overflow of machine integers would be too inefficient. The
> fact that (a) everyone puts -gnato in their options and (b) -gnato is
> now the default indicate that that thought was wrong (or, at any rate,
> became wrong a good while ago).

I rechecked the ARM 11.5 (16 and 27/2) again. You are correct. The implementer is allowed to suppress Overflow_Check instead of language required overflow check.


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
                   ` (2 preceding siblings ...)
  2018-05-21 15:57 ` Lucretia
@ 2018-05-21 19:11 ` Paul Rubin
  2018-05-22  0:39   ` Jere
  2018-05-21 20:43 ` nrs5134
  4 siblings, 1 reply; 16+ messages in thread
From: Paul Rubin @ 2018-05-21 19:11 UTC (permalink / raw)


> Should exceeding the range of Integer wrap around a la C?

It should raise a constraint error unless you turn off the check.  I
don't know if there is a specified result mandated if you have an
overflow with the check turned off.

In C, unsigned integer overflow is undefined behaviour, like a subscript
overflow.  Wraparound is one common result because of how machine
arithmetic works, but it is not guaranteed.  The program could instead
crash, or delete your files, or anything else.  See here:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
                   ` (3 preceding siblings ...)
  2018-05-21 19:11 ` Paul Rubin
@ 2018-05-21 20:43 ` nrs5134
  2018-05-22 17:52   ` Björn Lundin
  4 siblings, 1 reply; 16+ messages in thread
From: nrs5134 @ 2018-05-21 20:43 UTC (permalink / raw)


Thanks all for the replies! Good to know that this is a case of my compiler being out of date, not me losing my mind. I'll eventually get around to building a newer GNAT, but that's a headache I'd rather save for another day. As for project files, I'm sure those will have their place in my learning eventually, but I'm still just getting oriented. Still, a nice thing to have seen ahead of time.

Cheers,
NS

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 19:11 ` Paul Rubin
@ 2018-05-22  0:39   ` Jere
  2018-05-22  0:58     ` Dan'l Miller
  2018-05-22  1:36     ` Paul Rubin
  0 siblings, 2 replies; 16+ messages in thread
From: Jere @ 2018-05-22  0:39 UTC (permalink / raw)


On Monday, May 21, 2018 at 3:11:45 PM UTC-4, Paul Rubin wrote:
> > Should exceeding the range of Integer wrap around a la C?
> SNIPPED..
> 
> In C, unsigned integer overflow is undefined behaviour, like a subscript
> overflow.  Wraparound is one common result because of how machine
> arithmetic works, but it is not guaranteed.  The program could instead
> crash, or delete your files, or anything else.  See here:
> 
> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

Just wanted to point this out because I think you have a typo, but 
overflow for unsigned integers is completely defined in the C standard.
It is considered wraparound logic [1].  Signed integer overflow is 
undefined behavior however.

[1] Section 6.2.5/9 of the C11 standard


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-22  0:39   ` Jere
@ 2018-05-22  0:58     ` Dan'l Miller
  2018-05-22  1:36     ` Paul Rubin
  1 sibling, 0 replies; 16+ messages in thread
From: Dan'l Miller @ 2018-05-22  0:58 UTC (permalink / raw)


On Monday, May 21, 2018 at 7:39:54 PM UTC-5, Jere wrote:
> On Monday, May 21, 2018 at 3:11:45 PM UTC-4, Paul Rubin wrote:
> > > Should exceeding the range of Integer wrap around a la C?
> > SNIPPED..
> > 
> > In C, unsigned integer overflow is undefined behaviour, like a subscript
> > overflow.  Wraparound is one common result because of how machine
> > arithmetic works, but it is not guaranteed.  The program could instead
> > crash, or delete your files, or anything else.  See here:
> > 
> > http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
> 
> Just wanted to point this out because I think you have a typo, but 
> overflow for unsigned integers is completely defined in the C standard.
> It is considered wraparound logic [1].  Signed integer overflow is 
> undefined behavior however.
> 
> [1] Section 6.2.5/9 of the C11 standard

Yes, it has been there for quite some time, all the way back to ANSI C in 1989, IIRC.  P.J. Plaugher was the main driver of modulo arithmetic as the sound theoretical basis of unsigned integer types' overflow (and underflow below zero).  Standard C has a different concept of byte though:  sometimes 8-bit, sometimes 9-bit, sometimes 16-bit, sometimes 32-bit.  So •when• an unsigned char overflows to wrap around back to zero via modulo arithmetic can vary per target hardware ISA.

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-22  0:39   ` Jere
  2018-05-22  0:58     ` Dan'l Miller
@ 2018-05-22  1:36     ` Paul Rubin
  1 sibling, 0 replies; 16+ messages in thread
From: Paul Rubin @ 2018-05-22  1:36 UTC (permalink / raw)


Jere <jhb.chat@gmail.com> writes:
> Just wanted to point this out because I think you have a typo, but 
> overflow for unsigned integers is completely defined in the C standard.

Sorry yes of course you're right, it was a typo, I meant to say signed.

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-21 20:43 ` nrs5134
@ 2018-05-22 17:52   ` Björn Lundin
  2018-05-22 20:11     ` nrs5134
  0 siblings, 1 reply; 16+ messages in thread
From: Björn Lundin @ 2018-05-22 17:52 UTC (permalink / raw)


On 2018-05-21 22:43, nrs5134@gmail.com wrote:


>I'll eventually get around to building a newer GNAT, 

Building? Why? what platform are you on?


-- 
--
Björn


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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-22 17:52   ` Björn Lundin
@ 2018-05-22 20:11     ` nrs5134
  2018-05-22 20:23       ` Björn Lundin
  2018-05-23  7:35       ` Dmitry A. Kazakov
  0 siblings, 2 replies; 16+ messages in thread
From: nrs5134 @ 2018-05-22 20:11 UTC (permalink / raw)


Debian 8 ("Jessie"). The official Debian repo has GNAT 4.9.2. I have a local built-from-source GCC 8 that I use to play with newer Fortran features. I wasn't interested in Ada at the time, so I excluded it from the build. 

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-22 20:11     ` nrs5134
@ 2018-05-22 20:23       ` Björn Lundin
  2018-05-23  7:35       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 16+ messages in thread
From: Björn Lundin @ 2018-05-22 20:23 UTC (permalink / raw)


On 2018-05-22 22:11, nrs5134@gmail.com wrote:
> Debian 8 ("Jessie"). The official Debian repo has GNAT 4.9.2. I have a local built-from-source GCC 8 that I use to play with newer Fortran features. I wasn't interested in Ada at the time, so I excluded it from the build. 
> 

You can download the GPL2017 version from adacore.
Far more modern.
However, whatever it produces becomes GPL

Then switch between the two by setting/unsetting the GPL2017 first in
PATH or not


-- 
--
Björn

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

* Re: Should exceeding the range of Integer wrap around a la C?
  2018-05-22 20:11     ` nrs5134
  2018-05-22 20:23       ` Björn Lundin
@ 2018-05-23  7:35       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 16+ messages in thread
From: Dmitry A. Kazakov @ 2018-05-23  7:35 UTC (permalink / raw)


On 22/05/2018 22:11, nrs5134@gmail.com wrote:
> Debian 8 ("Jessie"). The official Debian repo has GNAT 4.9.2. I have a local built-from-source GCC 8 that I use to play with newer Fortran features. I wasn't interested in Ada at the time, so I excluded it from the build.

Debian "buster" has GNAT 8.x already.

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

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

end of thread, other threads:[~2018-05-23  7:35 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-21 15:23 Should exceeding the range of Integer wrap around a la C? nrs5134
2018-05-21 15:27 ` Jacob Sparre Andersen
2018-05-21 15:45 ` Anh Vo
2018-05-21 16:46   ` Simon Wright
2018-05-21 18:47     ` Anh Vo
2018-05-21 15:57 ` Lucretia
2018-05-21 16:49   ` Simon Wright
2018-05-21 19:11 ` Paul Rubin
2018-05-22  0:39   ` Jere
2018-05-22  0:58     ` Dan'l Miller
2018-05-22  1:36     ` Paul Rubin
2018-05-21 20:43 ` nrs5134
2018-05-22 17:52   ` Björn Lundin
2018-05-22 20:11     ` nrs5134
2018-05-22 20:23       ` Björn Lundin
2018-05-23  7:35       ` Dmitry A. Kazakov

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