comp.lang.ada
 help / color / mirror / Atom feed
* 'for cursor in container.first loop' bug?
@ 2014-08-28 17:56 Stephen Leake
  2014-08-28 19:56 ` Randy Brukardt
  2014-08-28 20:46 ` Simon Wright
  0 siblings, 2 replies; 6+ messages in thread
From: Stephen Leake @ 2014-08-28 17:56 UTC (permalink / raw)


I'm trying to use the 'for cursor in container.first loop' syntax in Ada
2012 with my own container, and having lots of problems.

So first I tried a simple example using Ada.Containers.Vector, with GNAT
2014:

with Ada.Text_Io; use Ada.Text_Io;
with Ada.Containers.Vectors;
procedure Try_Containers
is
   package Integer_Vectors is new Ada.Containers.Vectors (Natural, Integer);
   use Integer_Vectors;

   A : Vector := To_Vector (1, 10);
begin
   Loop_1 :
   for Element of A loop
      Put_Line ("A (i) => " & Integer'Image (Element));
      -- can't do Element := 2;
   end loop Loop_1;

   Loop_2 :
   for Cursor in First (A) loop
      Put_Line ("A (I) => " & Integer'Image (Element (Cursor)));
      Replace_Element (A, Cursor, 2);
      Reference (A, Cursor) := 2;
   end loop Loop_2;

end Try_Containers;

This gives compilation errors:

gnatmake -k ../try_containers.adb
gcc -c -I../ -I- ../try_containers.adb
try_containers.adb:17:28: invalid prefix in call
try_containers.adb:17:28: invalid prefix in selected component "I572b"
gnatmake: "../try_containers.adb" compilation error

Same error (with a different generated name) with GnatPro 7.2.

Commenting out loop_2 gives the expected results.

Am I missing something simple, or is this a compiler bug? At the very
least, it's not a good error message.

-- 
-- Stephe

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

* Re: 'for cursor in container.first loop' bug?
  2014-08-28 17:56 'for cursor in container.first loop' bug? Stephen Leake
@ 2014-08-28 19:56 ` Randy Brukardt
  2014-08-29 13:52   ` Stephen Leake
  2014-08-28 20:46 ` Simon Wright
  1 sibling, 1 reply; 6+ messages in thread
From: Randy Brukardt @ 2014-08-28 19:56 UTC (permalink / raw)


"Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message 
news:85y4u8xztj.fsf@stephe-leake.org...
> I'm trying to use the 'for cursor in container.first loop' syntax in Ada
> 2012 with my own container, and having lots of problems.
>
> So first I tried a simple example using Ada.Containers.Vector, with GNAT
> 2014:
>
> with Ada.Text_Io; use Ada.Text_Io;
> with Ada.Containers.Vectors;
> procedure Try_Containers
> is
>   package Integer_Vectors is new Ada.Containers.Vectors (Natural, 
> Integer);
>   use Integer_Vectors;
>
>   A : Vector := To_Vector (1, 10);
> begin
>   Loop_1 :
>   for Element of A loop
>      Put_Line ("A (i) => " & Integer'Image (Element));
>      -- can't do Element := 2;
>   end loop Loop_1;
>
>   Loop_2 :
>   for Cursor in First (A) loop
>      Put_Line ("A (I) => " & Integer'Image (Element (Cursor)));
>      Replace_Element (A, Cursor, 2);
>      Reference (A, Cursor) := 2;
>   end loop Loop_2;
>
> end Try_Containers;
>
> This gives compilation errors:
>
> gnatmake -k ../try_containers.adb
> gcc -c -I../ -I- ../try_containers.adb
> try_containers.adb:17:28: invalid prefix in call
> try_containers.adb:17:28: invalid prefix in selected component "I572b"
> gnatmake: "../try_containers.adb" compilation error
>
> Same error (with a different generated name) with GnatPro 7.2.
>
> Commenting out loop_2 gives the expected results.
>
> Am I missing something simple, or is this a compiler bug? At the very
> least, it's not a good error message.

You're missing something simple: "First" is not an iterator (it returns a 
cursor). You need to use one of the functions named "Iterate" that return a 
value that has an iterator type:

Loop_2 :
for Cursor in Iterate (A) loop

I'd still call it a bug, though, because the error message is inpenatrable 
for something simple (a violation of 5.5.2(3/3)). Indeed, this shouldn't 
even resolve.

I checked the two more recent GNAT compilers that I have (Gnatpro 7.2.2 and 
a wavefront), but they both have this message. I'd report it as a bug, 
because you probably wasted at lot of time (and even some of mine) on this 
rather simple mistake.

I was a bit surprised by this, because I thought the new ACATS tests covered 
this. (After some checking...) Interestingly, there is a test that checks 
for this sort of problem, and it produces sensible error messages for cases 
like:
    95.    for Item in Sparse_Cursor loop                            --  
ERROR:
                       |
        >>> cannot iterate over "Cursor"
        >>> to iterate directly over the elements of a container, write "of 
Sparse_Cursor"

   116.    for Item of Sparse_Cursor loop                            --  
ERROR:
               |
        >>> cannot iterate over "Cursor"

But your test (which looks the same to me) produces gibberish. This is 
obviously more subtle than I understand. Time to get some use out of your 
AdaCore support contract. :-)

                                        Randy.




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

* Re: 'for cursor in container.first loop' bug?
  2014-08-28 17:56 'for cursor in container.first loop' bug? Stephen Leake
  2014-08-28 19:56 ` Randy Brukardt
@ 2014-08-28 20:46 ` Simon Wright
  2014-08-29  3:16   ` Randy Brukardt
  2014-08-29 14:03   ` Stephen Leake
  1 sibling, 2 replies; 6+ messages in thread
From: Simon Wright @ 2014-08-28 20:46 UTC (permalink / raw)


While scratching my head over 5.5.2 Generalized Loop Iteration, I looked
at A.18.32 Example of Container Use[1] and tried compiling with GNAT GPL
2014 and GCC 4.9.0. The full example compiled fine, but when I attempted
the substitution in (29) this happened:

    55.          -- Update minimum distance to newly reachable nodes.
    56.          for E of G (Next) loop
    57.             if not Reached(E.To) then
    58.                Nearest_Distance := E.Length + So_Far(Next);
    59.                if Nearest_Distance < So_Far(E.To) then
    60.                   Reached_From(E.To) := Next;
    61.                   So_Far(E.To) := Nearest_Distance;
    62.                end if;
    63.             end if;
    64.          end loop;

(so the original was OK, but ...)

    65.          for C in G (Next).Iterate loop
    66.             declare
    67.                E : Edge renames G (Next)(C).all;
                                        |
        >>> access type required in prefix of explicit dereference

    68.             begin
    69.                if not Reached(E.To) then
                                      |
        >>> invalid prefix in selected component "E"

    70.                   Nearest_Distance := E.Length + So_Far(Next);
                                              |
        >>> invalid prefix in selected component "E"

    71.                   if Nearest_Distance < So_Far(E.To) then
                                                       |
        >>> invalid prefix in selected component "E"

    72.                      Reached_From(E.To) := Next;
                                          |
        >>> invalid prefix in selected component "E"

    73.                      So_Far(E.To) := Nearest_Distance;
                                    |
        >>> invalid prefix in selected component "E"

    74.                   end if;
    75.                end if;
    76.             end;
    77.          end loop;
 

[1] http://www.ada-auth.org/standards/12rm/html/RM-A-18-32.html


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

* Re: 'for cursor in container.first loop' bug?
  2014-08-28 20:46 ` Simon Wright
@ 2014-08-29  3:16   ` Randy Brukardt
  2014-08-29 14:03   ` Stephen Leake
  1 sibling, 0 replies; 6+ messages in thread
From: Randy Brukardt @ 2014-08-29  3:16 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lyfvggibpz.fsf@pushface.org...
> While scratching my head over 5.5.2 Generalized Loop Iteration, I looked
> at A.18.32 Example of Container Use[1] and tried compiling with GNAT GPL
> 2014 and GCC 4.9.0. The full example compiled fine, but when I attempted
> the substitution in (29) this happened:

Yes, this is known. Had you used the bleeding edge RM 
(http://www.ada-auth.org/standards/ada2x.html) you would have noticed that 
this example is one of many corrections to Ada 2012. (There is enough that 
WG 9 has ordered us to produce a Corrigendum of fixes by the end of next 
year.)

The story here is simply that your editor (that would me) had for some 
reason gotten the wrong notion of how generalized references worked. He then 
carefully used this wrong notion in RM examples and also in some examples 
that he gave to John Barnes for use in the Rationale. Both the RM and the 
Rationale required correction.

Specifically:

...
>    65.          for C in G (Next).Iterate loop
>    66.             declare
>    67.                E : Edge renames G (Next)(C).all;
No .all here; this should be:
              E : Edge renames G (Next)(C);

and the rest of the errors are a cascade.

There's an extra .all in A.18.32(31/4) as well.

Precisely why I was convinced that we needed that .all will have to remain a 
mystery. The rules are clear enough. (Most likely, some of the examples I 
posted here on cla probably had this misconception as well.)

                                Randy.


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

* Re: 'for cursor in container.first loop' bug?
  2014-08-28 19:56 ` Randy Brukardt
@ 2014-08-29 13:52   ` Stephen Leake
  0 siblings, 0 replies; 6+ messages in thread
From: Stephen Leake @ 2014-08-29 13:52 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message 
> news:85y4u8xztj.fsf@stephe-leake.org...
>>
>>   Loop_2 :
>>   for Cursor in First (A) loop
>>      Put_Line ("A (I) => " & Integer'Image (Element (Cursor)));
>>      Replace_Element (A, Cursor, 2);
>>      Reference (A, Cursor) := 2;
>>   end loop Loop_2;
>>
>> gnatmake -k ../try_containers.adb
>> gcc -c -I../ -I- ../try_containers.adb
>> try_containers.adb:17:28: invalid prefix in call
>> try_containers.adb:17:28: invalid prefix in selected component "I572b"
>>
>> Am I missing something simple, or is this a compiler bug? At the very
>> least, it's not a good error message.
>
> You're missing something simple: "First" is not an iterator (it returns a 
> cursor). You need to use one of the functions named "Iterate" that return a 
> value that has an iterator type:
>
> Loop_2 :
> for Cursor in Iterate (A) loop

Ah, thanks. That fixed it.

> I'd still call it a bug, though, because the error message is inpenatrable 
> for something simple (a violation of 5.5.2(3/3)). Indeed, this shouldn't 
> even resolve.

I'll report it.

-- 
-- Stephe

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

* Re: 'for cursor in container.first loop' bug?
  2014-08-28 20:46 ` Simon Wright
  2014-08-29  3:16   ` Randy Brukardt
@ 2014-08-29 14:03   ` Stephen Leake
  1 sibling, 0 replies; 6+ messages in thread
From: Stephen Leake @ 2014-08-29 14:03 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> While scratching my head over 5.5.2 Generalized Loop Iteration, I looked
> at A.18.32 Example of Container Use[1] and tried compiling with GNAT GPL
> 2014 and GCC 4.9.0. The full example compiled fine, but when I attempted
> the substitution in (29) this happened:
>
>     65.          for C in G (Next).Iterate loop
>     66.             declare
>     67.                E : Edge renames G (Next)(C).all;
>                                         |
>         >>> access type required in prefix of explicit dereference

This should be:

               E : Edge renames Element (C);

Randy, can you take it from here, or do we need to submit an Ada
Comment?

-- 
-- Stephe


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

end of thread, other threads:[~2014-08-29 14:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-28 17:56 'for cursor in container.first loop' bug? Stephen Leake
2014-08-28 19:56 ` Randy Brukardt
2014-08-29 13:52   ` Stephen Leake
2014-08-28 20:46 ` Simon Wright
2014-08-29  3:16   ` Randy Brukardt
2014-08-29 14:03   ` Stephen Leake

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