comp.lang.ada
 help / color / mirror / Atom feed
* Compiler checking of String lengths during assignment (Newbie Question)
@ 2015-01-09 22:50 isaac1.0
  2015-01-09 23:10 ` Simon Wright
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: isaac1.0 @ 2015-01-09 22:50 UTC (permalink / raw)


Maybe this is obvious to the experts, but I'm new to Ada.

I'm using the Libre GNAT GPS 2014. I've a program that looks roughly like this:
==============================================
procedure Main is
   Head : String (1..5) := "XXX_N";
   i : Positive;
   Line : String := "12312312312312312";
   
begin
.
.
.
   i := 2;
   Head := "123";
   Head := Line(1 .. 2);
   Head := Line(i+2 .. i+4);
.
.
.
end Main;
==============================================

The first 2 cases produces an error during the build, as expected, because Head is known to be length of 5 and I'm assigning something of a different length.
The 3rd assignment there does NOT produce an error, no warning no nothing even though this clearly violates the same check.

What does happen is that at runtime the execution is incorrect. It doesn't even terminate in a horrible disaster (which would be preferable). The full program actually just reads a text file (for now) and in this case because the assigned length is incorrect, it just reads a few lines then bails claiming unable to read the text file.

Aren't Ada compilers supposed to prevent stupid errors like this? Or is there some user stupidity here that I'm not seeing...?

Thanks,
Isaac


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
@ 2015-01-09 23:10 ` Simon Wright
  2015-01-09 23:20   ` Stefan.Lucks
  2015-01-09 23:53 ` Shark8
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2015-01-09 23:10 UTC (permalink / raw)


isaac1.0@gmail.com writes:

> The first 2 cases produces an error during the build, as expected,
> because Head is known to be length of 5 and I'm assigning something of
> a different length.
> The 3rd assignment there does NOT produce an error, no warning no
> nothing even though this clearly violates the same check.
>
> What does happen is that at runtime the execution is incorrect. It
> doesn't even terminate in a horrible disaster (which would be
> preferable). The full program actually just reads a text file (for
> now) and in this case because the assigned length is incorrect, it
> just reads a few lines then bails claiming unable to read the text
> file.

This sounds as if it might be related to GCC PR ada/61466[1]. Are you
optimising?

> Aren't Ada compilers supposed to prevent stupid errors like this? Or
> is there some user stupidity here that I'm not seeing...?

Sometimes compilers do have bugs.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61466


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 23:10 ` Simon Wright
@ 2015-01-09 23:20   ` Stefan.Lucks
  2015-01-10 12:43     ` Brian Drummond
  0 siblings, 1 reply; 15+ messages in thread
From: Stefan.Lucks @ 2015-01-09 23:20 UTC (permalink / raw)


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

On Fri, 9 Jan 2015, Simon Wright wrote:

>> The first 2 cases produces an error during the build, as expected,
>> because Head is known to be length of 5 and I'm assigning something of
>> a different length.

I believe, all three should generate a run-time error (most likely a 
Constraint_Error).

But a good compiler should also warn you about the run-time error, and 
maybe you have set your compiler to treat warnings as errors (which is
not a bad idea).

>> The 3rd assignment there does NOT produce an error, no warning no
>> nothing even though this clearly violates the same check.

This is a compiler bug!


------  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] 15+ messages in thread

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
  2015-01-09 23:10 ` Simon Wright
@ 2015-01-09 23:53 ` Shark8
  2015-01-10  0:18 ` Jeffrey Carter
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Shark8 @ 2015-01-09 23:53 UTC (permalink / raw)


On 09-Jan-15 15:50, isaac1.0@gmail.com wrote:
> Aren't Ada compilers supposed to prevent stupid errors like this?
> Or is there some user stupidity here that I'm not seeing...?

I think you've found a compiler bug.
(And, IMO, it /should/ error-out like the others.)


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
  2015-01-09 23:10 ` Simon Wright
  2015-01-09 23:53 ` Shark8
@ 2015-01-10  0:18 ` Jeffrey Carter
  2015-01-10  1:48 ` Adam Beneschan
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2015-01-10  0:18 UTC (permalink / raw)


On 01/09/2015 03:50 PM, isaac1.0@gmail.com wrote:
> 
> The first 2 cases produces an error during the build, as expected, because
> Head is known to be length of 5 and I'm assigning something of a different
> length.

They might produce warnings, but not errors, unless you've told the compiler to
treat warnings as errors.

> The 3rd assignment there does NOT produce an error, no warning no nothing
> even though this clearly violates the same check.

Have you tried compiling with -gnatwa?

> What does happen is that at runtime the execution is incorrect. It doesn't
> even terminate in a horrible disaster (which would be preferable). The full
> program actually just reads a text file (for now) and in this case because
> the assigned length is incorrect, it just reads a few lines then bails
> claiming unable to read the text file.

Do you have an exception handler?

> Aren't Ada compilers supposed to prevent stupid errors like this? Or is there
> some user stupidity here that I'm not seeing...?

Unless you give us a complete program, the options used when building it, the
exact messages output when run, and what you expected the result of running it
to be, we can't tell.

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail
02

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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
                   ` (2 preceding siblings ...)
  2015-01-10  0:18 ` Jeffrey Carter
@ 2015-01-10  1:48 ` Adam Beneschan
  2015-01-10 10:03 ` Pascal Obry
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Adam Beneschan @ 2015-01-10  1:48 UTC (permalink / raw)


On Friday, January 9, 2015 at 2:50:18 PM UTC-8, isaa...@gmail.com wrote:
> Maybe this is obvious to the experts, but I'm new to Ada.
> 
> I'm using the Libre GNAT GPS 2014. I've a program that looks roughly like this:
> ==============================================
> procedure Main is
>    Head : String (1..5) := "XXX_N";
>    i : Positive;
>    Line : String := "12312312312312312";
>    
> begin
> .
> .
> .
>    i := 2;
>    Head := "123";
>    Head := Line(1 .. 2);
>    Head := Line(i+2 .. i+4);
> .
> .
> .
> end Main;
> ==============================================
> 
> The first 2 cases produces an error during the build, as expected, because Head is known to be length of 5 and I'm assigning something of a different length.
> The 3rd assignment there does NOT produce an error, no warning no nothing even though this clearly violates the same check.

I do get a warning with GCC 4.5.4.  And, as expected, I get a Constraint_Error when I run it.  If you're not getting a warning, it's probably a compiler bug.  If it's not generating Constraint_Error, it's definitely a compiler bug unless you've done something that turns off checking.

However, it's important to realize that what's clear to us won't necessarily be clear to a compiler.  The range Line(i+2 .. i+4) will always have 'Length 3, no matter what "i" is.  But we know that because we know basic algebra.  It's not easy for a compiler to do the kinds of expression manipulation needed to figure something like this out.  In fact, I don't get a warning with this program:

    procedure Main is
        Head : String (1..5) := "XXX_N"; 
        i : Positive; 
        Line : String := "12312312312312312"; 

        procedure Do_Nothing is null;
    begin 
        i := 2;
        Do_Nothing; 
        Head := Line(i+2 .. i+4); 
    end Main;

Apparently, the reason I get a warning without the Do_Nothing call is that the compiler keeps track of the values it knows about, so it can compute i+2 and i+4 and see that the length will be wrong.  But with the procedure call inserted, the compiler assumes that the procedure could change "i", so it can no longer track the value.  The compiler doesn't figure out that Do_Nothing doesn't change the value of "i", and it doesn't figure out that i+2 .. i+4 will always be a range of 3 regardless of the value.  So it doesn't produce a warning.  Of course it still gets a Constraint_Error at run time.

                                 -- Adam


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
                   ` (3 preceding siblings ...)
  2015-01-10  1:48 ` Adam Beneschan
@ 2015-01-10 10:03 ` Pascal Obry
  2015-01-10 10:54 ` Simon Wright
  2015-01-15 20:44 ` isaac1.0
  6 siblings, 0 replies; 15+ messages in thread
From: Pascal Obry @ 2015-01-10 10:03 UTC (permalink / raw)


Le vendredi 09 janvier 2015 à 14:50 -0800, isaac1.0@gmail.com a écrit : 
> Aren't Ada compilers supposed to prevent stupid errors like this? Or is there some user stupidity here that I'm not seeing...?

No, at compile time is only detect error that are statically computable.

Here i+2 and i+4 are not, i  is not a constant. So a runtime check is
issued.

Regards,

-- 
  Pascal Obry /  Magny Les Hameaux (78)

  The best way to travel is by means of imagination

  http://v2p.fr.eu.org
  http://www.obry.net

  gpg --keyserver keys.gnupg.net --recv-key F949BD3B




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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
                   ` (4 preceding siblings ...)
  2015-01-10 10:03 ` Pascal Obry
@ 2015-01-10 10:54 ` Simon Wright
  2015-01-15 20:44 ` isaac1.0
  6 siblings, 0 replies; 15+ messages in thread
From: Simon Wright @ 2015-01-10 10:54 UTC (permalink / raw)


I just ran this and got warnings on all 3 lines, with GNAT GPL 2014, GCC
4.9.1, GCC 5.0 (experimental).

isaac1.adb:8:12: warning: wrong length for array of subtype of "Standard.String" defined at line 2
isaac1.adb:8:12: warning: "Constraint_Error" will be raised at run time
isaac1.adb:9:12: warning: too few elements for subtype of "Standard.String" defined at line 2
isaac1.adb:9:12: warning: "Constraint_Error" will be raised at run time
isaac1.adb:10:12: warning: too few elements for subtype of "Standard.String" defined at line 2
isaac1.adb:10:12: warning: "Constraint_Error" will be raised at run time

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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 23:20   ` Stefan.Lucks
@ 2015-01-10 12:43     ` Brian Drummond
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Drummond @ 2015-01-10 12:43 UTC (permalink / raw)


On Sat, 10 Jan 2015 00:20:11 +0100, Stefan.Lucks wrote:

> On Fri, 9 Jan 2015, Simon Wright wrote:
> 
>>> The first 2 cases produces an error during the build, as expected,
>>> because Head is known to be length of 5 and I'm assigning something of
>>> a different length.
> 
> I believe, all three should generate a run-time error (most likely a
> Constraint_Error).

The FSF Gnat 4.9.1 (Debian package) compiles with warnings, and all three 
raise Constraint Error.

The first one reports "length check failed", 
the other two "range check failed".

We often hear that the FSF compiler "lags behind" the Libre one and maybe 
in some respects it does, but apparently, that doesn't mean it's always 
worse.

- Brian

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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
                   ` (5 preceding siblings ...)
  2015-01-10 10:54 ` Simon Wright
@ 2015-01-15 20:44 ` isaac1.0
  2015-01-15 21:18   ` Simon Wright
  6 siblings, 1 reply; 15+ messages in thread
From: isaac1.0 @ 2015-01-15 20:44 UTC (permalink / raw)


On Friday, January 9, 2015 at 2:50:18 PM UTC-8, isaa...@gmail.com wrote:
> Maybe this is obvious to the experts, but I'm new to Ada.
> 
> I'm using the Libre GNAT GPS 2014. I've a program that looks roughly like this:
> ==============================================
> procedure Main is
>    Head : String (1..5) := "XXX_N";
>    i : Positive;
>    Line : String := "12312312312312312";
>    
> begin
> .
> .
> .
>    i := 2;
>    Head := "123";
>    Head := Line(1 .. 2);
>    Head := Line(i+2 .. i+4);
> .
> .
> .
> end Main;
> ==============================================
> 
> The first 2 cases produces an error during the build, as expected, because Head is known to be length of 5 and I'm assigning something of a different length.
> The 3rd assignment there does NOT produce an error, no warning no nothing even though this clearly violates the same check.
> 
> What does happen is that at runtime the execution is incorrect. It doesn't even terminate in a horrible disaster (which would be preferable). The full program actually just reads a text file (for now) and in this case because the assigned length is incorrect, it just reads a few lines then bails claiming unable to read the text file.
> 
> Aren't Ada compilers supposed to prevent stupid errors like this? Or is there some user stupidity here that I'm not seeing...?
> 
> Thanks,
> Isaac

Thanks for all your responses. There are 2 issues I think.
One is the compiler. Mine says GNAT GPL 2014 (20140331) and gcc is 4.7.4

gcc -c -I- -gnatA E:\Projects\Test\src\main.adb
main.adb:23:27: warning: wrong length for array of subtype of "Standard.String" defined at line 9
main.adb:23:27: warning: "Constraint_Error" will be raised at run time
main.adb:24:27: warning: too few elements for subtype of "Standard.String" defined at line 9
main.adb:24:27: warning: "Constraint_Error" will be raised at run time

So I get the 2 warnings that are expected, but the 3rd one is missed. I'm no compiler expert, but if you say it's difficult for the compiler to sort out arithmetic logic like that, then maybe this is the case. If a newer compiler is not showing the problem, then maybe this has already been solved.

The second issue is user stupidity. In fact, all 3 cases do generate run time error, as expected. The reason I'm not seeing it on the 3rd case is buggy exception handling code. In my sample, there is some error that causes the run-time error on length checking to fall through and show as something else. 


Thank you again for all your help. Back to more fun & games with Ada!


Isaac


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-15 20:44 ` isaac1.0
@ 2015-01-15 21:18   ` Simon Wright
  2015-01-15 22:30     ` Jeffrey Carter
  2015-01-15 22:32     ` Jeffrey Carter
  0 siblings, 2 replies; 15+ messages in thread
From: Simon Wright @ 2015-01-15 21:18 UTC (permalink / raw)


isaac1.0@gmail.com writes:

> One is the compiler. Mine says GNAT GPL 2014 (20140331) and gcc is 4.7.4
>
> gcc -c -I- -gnatA E:\Projects\Test\src\main.adb
> main.adb:23:27: warning: wrong length for array of subtype of
> "Standard.String" defined at line 9
> main.adb:23:27: warning: "Constraint_Error" will be raised at run time
> main.adb:24:27: warning: too few elements for subtype of
> "Standard.String" defined at line 9
> main.adb:24:27: warning: "Constraint_Error" will be raised at run time
>
> So I get the 2 warnings that are expected, but the 3rd one is
> missed. I'm no compiler expert, but if you say it's difficult for the
> compiler to sort out arithmetic logic like that, then maybe this is
> the case. If a newer compiler is not showing the problem, then maybe
> this has already been solved.

As I think I've said before, with the same compiler (on Mac OS X, but
I'd be _very_ surprised if that made a difference) I get warnings on all
three lines.

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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-15 21:18   ` Simon Wright
@ 2015-01-15 22:30     ` Jeffrey Carter
  2015-01-15 22:32     ` Jeffrey Carter
  1 sibling, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2015-01-15 22:30 UTC (permalink / raw)


On 01/15/2015 02:18 PM, Simon Wright wrote:
> 
> As I think I've said before, with the same compiler (on Mac OS X, but
> I'd be _very_ surprised if that made a difference) I get warnings on all
> three lines.

You don't have the code that the OP compiled, since he didn't post it. There's
no telling what might lie between "begin" and line 25 in that code that would
cause the difference.

-- 
Jeff Carter
"Mr. President, we must not allow a mine-shaft gap!"
Dr. Strangelove
33


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-15 21:18   ` Simon Wright
  2015-01-15 22:30     ` Jeffrey Carter
@ 2015-01-15 22:32     ` Jeffrey Carter
  2015-01-16  7:28       ` Simon Wright
  1 sibling, 1 reply; 15+ messages in thread
From: Jeffrey Carter @ 2015-01-15 22:32 UTC (permalink / raw)


On 01/15/2015 02:18 PM, Simon Wright wrote:
> 
> As I think I've said before, with the same compiler (on Mac OS X, but
> I'd be _very_ surprised if that made a difference) I get warnings on all
> three lines.

You don't have the code the OP compiled, since he didn't post it. There's no
telling what may appear between "begin" and the lines in question in that code.
As Duff showed, a null procedure call is enough to eliminate the warning on the
line using I.

-- 
Jeff Carter
"Mr. President, we must not allow a mine-shaft gap!"
Dr. Strangelove
33

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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-15 22:32     ` Jeffrey Carter
@ 2015-01-16  7:28       ` Simon Wright
  2015-01-16 15:44         ` Jeffrey Carter
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2015-01-16  7:28 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> On 01/15/2015 02:18 PM, Simon Wright wrote:
>> 
>> As I think I've said before, with the same compiler (on Mac OS X, but
>> I'd be _very_ surprised if that made a difference) I get warnings on
>> all three lines.
>
> You don't have the code the OP compiled, since he didn't post
> it. There's no telling what may appear between "begin" and the lines
> in question in that code.  As Duff showed, a null procedure call is
> enough to eliminate the warning on the line using I.

It was Adam, not Bob.

Adam showed that

   procedure Main is
      Head : String (1..5) := "XXX_N";
      i : Positive;
      Line : String := "12312312312312312";
      procedure Nothing is null;
   begin
      i := 2;
      Nothing;                   -- <<<<< prevents the 3rd warning 
      Head := "123";
      Head := Line(1 .. 2);
      Head := Line(i+2 .. i+4);
   end Main;

and, while I agree with you that the OP should have posted a compilable
example that demonstrated the problem, the posted code had nothing
between the assignment to i and the assignments to Head.


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

* Re: Compiler checking of String lengths during assignment (Newbie Question)
  2015-01-16  7:28       ` Simon Wright
@ 2015-01-16 15:44         ` Jeffrey Carter
  0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2015-01-16 15:44 UTC (permalink / raw)


On 01/16/2015 12:28 AM, Simon Wright wrote:
> 
> It was Adam, not Bob.

I apologize for the misattribution.

> and, while I agree with you that the OP should have posted a compilable
> example that demonstrated the problem, the posted code had nothing
> between the assignment to i and the assignments to Head.

True, but if the elided code is sufficiently complex, the compiler may have
given up trying to track the value of I, even though the code fragment alone is
simple enough for the compiler to do so. (I know nothing about the compiler code
that does that kind of tracking, but when faced with identical code that gives
different warnings when isolated than when embedded in other code, it seems
logical to assume that the presence of the other code is the reason.)

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84


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

end of thread, other threads:[~2015-01-16 15:44 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-09 22:50 Compiler checking of String lengths during assignment (Newbie Question) isaac1.0
2015-01-09 23:10 ` Simon Wright
2015-01-09 23:20   ` Stefan.Lucks
2015-01-10 12:43     ` Brian Drummond
2015-01-09 23:53 ` Shark8
2015-01-10  0:18 ` Jeffrey Carter
2015-01-10  1:48 ` Adam Beneschan
2015-01-10 10:03 ` Pascal Obry
2015-01-10 10:54 ` Simon Wright
2015-01-15 20:44 ` isaac1.0
2015-01-15 21:18   ` Simon Wright
2015-01-15 22:30     ` Jeffrey Carter
2015-01-15 22:32     ` Jeffrey Carter
2015-01-16  7:28       ` Simon Wright
2015-01-16 15:44         ` Jeffrey Carter

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