Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Simple loop with a strange output

111 views
Skip to first unread message

Luca Cappelletti

unread,
May 23, 2013, 9:53:19 AM5/23/13
to
Hello,

I'm using GNAT 4.6 via Debian 7

I've just compiled this simple code coming from a tutorial where I've just a little bit changed to fit my test:


with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure Hello is

procedure Raddoppia(Elemento: in out Integer) is
begin

Elemento := Elemento * 2;

end Raddoppia;

X : Integer;

begin

Put_Line("start counting");
New_Line;

X := 1;
while X < 1009999999 loop
Put(X);
New_Line;
Raddoppia(X);
end loop;

end Hello;

that produce the expected:

$./hello
Ciao a tutti sto usando Put_Line direttamente con la clausola use

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


now that strange error:

if you change the code using only the simple "loop - end loop" or change the number into the while from 1009999999 to 1099999999

my output will be an infinite sequence of zero

$./hello
0
0
0
0
...
0
...



do you know what's happening?

thank in advance,

Luca

Luca Cappelletti

unread,
May 23, 2013, 9:55:27 AM5/23/13
to
sorry there was a paste error from 2 text files the right output was:

$ ./hello
Start counting
thanks

Luca

Adam Beneschan

unread,
May 23, 2013, 10:37:24 AM5/23/13
to
On Thursday, May 23, 2013 6:53:19 AM UTC-7, Luca Cappelletti wrote:

> do you know what's happening?

Overflow.

The largest possible value of an "integer" type on this platform is (2**31)-1. So when X hits 2**30 and then you double it, the actual value, 2**31, won't fit in an integer. If you use the right flags when compiling (I don't remember what they are), this will cause a Constraint_Error to be raised. But since you didn't use those flags, the result will be whatever the processor returns, which will be -2**31. Since this is less than 1099999999, it will loop back and try to double it again; now when you double it the processor will return 0, and then you get stuck in an infinite loop.

-- Adam

Adam Beneschan

unread,
May 23, 2013, 10:41:24 AM5/23/13
to
On Thursday, May 23, 2013 7:37:24 AM UTC-7, Adam Beneschan wrote:
> On Thursday, May 23, 2013 6:53:19 AM UTC-7, Luca Cappelletti wrote:

> > do you know what's happening?

> Overflow.
>
> The largest possible value of an "integer" type on this platform is (2**31)-1. So when X hits 2**30 and then you double it, the actual value, 2**31, won't fit in an integer. If you use the right flags when compiling (I don't remember what they are),

OK, if you compile with -gnato, it will do the check, and now the program will die on a Constraint_Error instead of getting into an infinite loop.

-- Adam

Luca Cappelletti

unread,
May 23, 2013, 12:09:25 PM5/23/13
to
Yes this is the new output:

$ gnatmake -gnato hello.adb
gcc-4.4 -c -gnato hello.adb
gnatbind -x hello.ali
gnatlink hello.ali
$ ./hello
Start counting
1073741824

raised CONSTRAINT_ERROR : hello.adb:9 overflow check failed

do you know why the overflow checking is off by default?
I mean I expect gnat force me to understand my errors via it's own debug messages instead works closed how gcc do for C leaving developer into the dark

thank you very much

Luca

Simon Wright

unread,
May 23, 2013, 12:40:41 PM5/23/13
to
Luca Cappelletti <luca.cap...@gmail.com> writes:

> do you know why the overflow checking is off by default?

The explanation is here:
http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Controlling-Run_002dTime-Checks.html#index-g_t_0040option_007b_002dgnato_007d-_0028_0040command_007bgcc_007d_0029-595

or here, if that link got broken: http://goo.gl/ffIjp

Dirk Heinrichs

unread,
May 23, 2013, 4:41:46 PM5/23/13
to
Luca Cappelletti wrote:

> if you change the code using only the simple "loop - end loop" or change
> the number into the while from 1009999999 to 1099999999
>
> my output will be an infinite sequence of zero
>
> $./hello
> 0
> 0
> 0
> 0
> ...
> 0
> ...

Did you leave something out in your output? I get:

% ./hello
start counting
1073741824
-2147483648
0
0
0
0
0

And this is what I would expect, taking into account Adams and Simons
replies.

Bye...

Dirk
--
Dirk Heinrichs <dirk.he...@altum.de>
Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913
GPG Public Key C2E467BB | Jabber: dirk.he...@altum.de

Randy Brukardt

unread,
May 23, 2013, 5:34:47 PM5/23/13
to
"Simon Wright" <si...@pushface.org> wrote in message
news:lyppwh8...@pushface.org...
That's the official line, but I think if you asked most people at AdaCore
today, they'd tell you that it was a mistake.

But mistakes like this one aren't really fixable, because of all of the
existing code that would be at risk of breaking if they changed the default.
(That code would technically be wrong, but I doubt that would be much
consolation if it meant that the train refused to stop.)

This sort of thing is going to happen in any compiler that's been around a
while. There are certainly defaults in Janus/Ada that I wouldn't make the
default today, but breaking existing projects isn't really an option, so
such changes hardly ever are made.

Randy.


Simon Wright

unread,
May 24, 2013, 3:21:59 AM5/24/13
to
And most of us would agree that it was a mistake, too.

All my projects (free, and the ones I used to be paid for) use -gnato by
default. They don't use -fstack-check, because it wasn't reliable when I
was working out the project settings (and I could have really used it
when I needed a 500K stack to process some XML!).

I seriously doubt that any project where there was a possibility of a
train failing to stop would do something as risky as changing the
compiler without a thorough risk analysis. I wasn't allowed to, and
there were no trains involved (just point-defence missiles!)

Britt

unread,
May 24, 2013, 8:46:31 AM5/24/13
to
On Thursday, May 23, 2013 5:34:47 PM UTC-4, Randy Brukardt wrote:

> That's the official line, but I think if you asked most people
> at AdaCore today, they'd tell you that it was a mistake. But
> mistakes like this one aren't really fixable, because of all
> of the existing code that would be at risk of breaking if they
> changed the default.

I also view it was a mistake. I think there may have been an opportunity to correct it by making -gnato (overflow checking) implicit when the compiler is in Ada 2012 mode. Then a new switch would be needed to turn it off. This approach would have had little risk of breaking much existing code.

- Britt
0 new messages