Mega Search
23.2 Million


Sign Up

Make a donation  
'for cursor in container.first loop' bug?  
News Group: comp.lang.ada

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

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 28-Aug-2014, at 12:56 PM EST
From: Stephen Leake
 
Re: 'for cursor in container.first loop' bug?  
News Group: comp.lang.ada
Simon Wright  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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 9:03 AM EST
From: Stephen Leake
 
Re: 'for cursor in container.first loop' bug?  
News Group: comp.lang.ada
"Randy Brukardt"  writes:

> "Stephen Leake"  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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 8:52 AM EST
From: Stephen Leake
 
Re: 'for cursor in container.first loop' bug?  
News Group: comp.lang.ada
"Simon Wright"  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.



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 28-Aug-2014, at 10:16 PM EST
From: Randy Brukardt
 
Re: 'for cursor in container.first loop' bug?  
News Group: comp.lang.ada
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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 28-Aug-2014, at 9:46 PM EST
From: Simon Wright