comp.lang.ada
 help / color / mirror / Atom feed
* Possible GNAT problem with aliased parameters.
@ 2013-10-18 16:01 Shark8
  2013-10-18 16:51 ` sbelmont700
  0 siblings, 1 reply; 11+ messages in thread
From: Shark8 @ 2013-10-18 16:01 UTC (permalink / raw)


The Ada 2012 Rational says the following about Aliased parameters:

>    The other change in Ada 2012 concerning parameters is that they may be
>    explicitly marked aliased thus procedure P(X: aliased in out T; ... );
>    As a consequence within P we can write X'Access.

Yet, when such parameters are thus used (X'Access) the compiler generates the following message "access-to-variable designates constant" and fails the compilation.

-- Example:
-----------

    Package Test is
        Type Maze(<>) is tagged private;
        
        None : Aliased Constant Maze;
        
        Function Create( North, South, East, West : Aliased Maze'Class:= None )
          return Maze;
        
        
    Private
        
        Type Paths is Array(Positive range <>) of Access Maze'Class;
          
        Type Maze( Length : Natural ) is tagged record
            Exits : Paths(1..Length);
        end record;
        
        -- Note: Expression-function used so everything is defined in-spec.
        Function Create( North, South, East, West : Aliased Maze'Class:= None )
          return Maze is
          ( Maze'(Length => 4, Exits => (North'Access, South'Access, East'Access, West'Access)) );
          
          None : Aliased Constant Maze := ( Length => 0, Others => <> );
        
    End Test;


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-18 16:01 Possible GNAT problem with aliased parameters Shark8
@ 2013-10-18 16:51 ` sbelmont700
  2013-10-19  1:59   ` Randy Brukardt
  0 siblings, 1 reply; 11+ messages in thread
From: sbelmont700 @ 2013-10-18 16:51 UTC (permalink / raw)


Either your array has to be 'access constant', or your aliased parameter has to be 'in out'.  Though, as written, you will still fail the accessibility check...

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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-18 16:51 ` sbelmont700
@ 2013-10-19  1:59   ` Randy Brukardt
  2013-10-19  5:48     ` Shark8
  0 siblings, 1 reply; 11+ messages in thread
From: Randy Brukardt @ 2013-10-19  1:59 UTC (permalink / raw)


Right. To expand on this a bit: an "in" parameter is a constant, of course. 
"aliased" doesn't change that. If you want to be able to modify the 
parameter, it has to be an "in out" parameter.

Similarly, "aliased" doesn't change the accessibility rules (with one 
exception regarding function results), so you still have to use local access 
types. The primary reason we added it to the language is to allow the 
"reference" objects to work on containers (like the bounded containers) that 
directly contain the elements. Of course, we made it general enough that it 
can be used for other reasons as well.

                     Randy.

<sbelmont700@gmail.com> wrote in message 
news:12afac91-f0f3-4f89-ac0f-a61aaf7b8d4b@googlegroups.com...
> Either your array has to be 'access constant', or your aliased parameter 
> has to be 'in out'.  Though, as written, you will still fail the 
> accessibility check... 




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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-19  1:59   ` Randy Brukardt
@ 2013-10-19  5:48     ` Shark8
  2013-10-19  7:48       ` Dmitry A. Kazakov
  2013-10-19 14:30       ` sbelmont700
  0 siblings, 2 replies; 11+ messages in thread
From: Shark8 @ 2013-10-19  5:48 UTC (permalink / raw)


On Friday, October 18, 2013 7:59:58 PM UTC-6, Randy Brukardt wrote:
> Right. To expand on this a bit: an "in" parameter is a constant, of course. 
> "aliased" doesn't change that. If you want to be able to modify the 
> parameter, it has to be an "in out" parameter.

I see. That's not an issue in my little test-project, it's the same underlying idea: Have a node that has some number of other nodes as children. The common usage-case would be reading this sort of graph from a file (Write seldom, read many), which should mean that parameters needn't be modifiable.


> Similarly, "aliased" doesn't change the accessibility rules (with one 
> exception regarding function results), so you still have to use local access 
> types. 

I see that now -- and now I'm trying to figure a way to do it; possibly making the test-module a library-level unit (and thus on-par with the access level of the given package, assuming that it's also library-level, right?

> The primary reason we added it to the language is to allow the 
> "reference" objects to work on containers (like the bounded containers) that 
> directly contain the elements. Of course, we made it general enough that it 
> can be used for other reasons as well.

Right, I was hoping to avoid containers for the time being... and they wouldn't help in this instance, would they?


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-19  5:48     ` Shark8
@ 2013-10-19  7:48       ` Dmitry A. Kazakov
  2013-10-19 14:30       ` sbelmont700
  1 sibling, 0 replies; 11+ messages in thread
From: Dmitry A. Kazakov @ 2013-10-19  7:48 UTC (permalink / raw)


On Fri, 18 Oct 2013 22:48:58 -0700 (PDT), Shark8 wrote:

> Right, I was hoping to avoid containers for the time being... and they
> wouldn't help in this instance, would they?

No. Refactoring graph nodes (and subgraphs) requires [much] work that
standard containers do not. You will need reference counting scheme and
hash function of subgraphs.

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


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-19  5:48     ` Shark8
  2013-10-19  7:48       ` Dmitry A. Kazakov
@ 2013-10-19 14:30       ` sbelmont700
  2013-10-19 21:17         ` Shark8
  1 sibling, 1 reply; 11+ messages in thread
From: sbelmont700 @ 2013-10-19 14:30 UTC (permalink / raw)


On Saturday, October 19, 2013 1:48:58 AM UTC-4, Shark8 wrote:
> now I'm trying to figure a way to do it

The only way would be to hack it together with access discriminants:

type Maze (n : access Maze'Class;
           s : access Maze'Class;
           e : access Maze'Class;
           w : access Maze'Class) is tagged null record; 
        
function Create (North, South, East, West : aliased in out Maze'Class:= None) return Maze is
begin
   if Just_North then
      return Maze'(n => North'Access, null, null, null);
   elsif North_And_South then
      return Maze'(n => North'Access, South'Access, null, null);
   
   -- continue a bunch more times for all possibilities
   
   end if;

end Create;
   
This is a shame, because the aliased parameter/access discriminant method works so well for simple composition of one object, and extending it to arrays of objects would eliminate what is essentially the last unnecessary use of access types (I bemoaned the inability to pass around arrays of local access types awhile back in another thread, and this is another good example of why).

-sb


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-19 14:30       ` sbelmont700
@ 2013-10-19 21:17         ` Shark8
  2013-10-20  6:29           ` Shark8
  0 siblings, 1 reply; 11+ messages in thread
From: Shark8 @ 2013-10-19 21:17 UTC (permalink / raw)


On Saturday, October 19, 2013 8:30:05 AM UTC-6, sbelm...@gmail.com wrote:
> 
> function Create (North, South, East, West : aliased in out Maze'Class:= None) return Maze

That won't work; the default and IN OUT cannot be used together.

> The only way would be to hack it together with access discriminants:
>
> type Maze (n : access Maze'Class;
>           s : access Maze'Class;
>           e : access Maze'Class;
>           w : access Maze'Class) is tagged null record;

That's rather unfortunate; having them in an array-component would be the best for the processing I'm planning [where a "fore X of" would be nice]. (What I showed was a simplified example; there's a bit more in the actual structure [two Strings]).

>This is a shame, because the aliased parameter/access discriminant method works so well for simple composition of one object, and extending it to arrays of objects would eliminate what is essentially the last unnecessary use of access types (I bemoaned the inability to pass around arrays of local access types awhile back in another thread, and this is another good example of why). 

I think I understand what you're saying here; but would you give a usage-example of what you'd do with such?

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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-19 21:17         ` Shark8
@ 2013-10-20  6:29           ` Shark8
  2013-10-20 15:33             ` sbelmont700
  0 siblings, 1 reply; 11+ messages in thread
From: Shark8 @ 2013-10-20  6:29 UTC (permalink / raw)


On Saturday, October 19, 2013 3:17:17 PM UTC-6, Shark8 wrote:
> 
> 

My solution was to use renames on the parameters and then allocate new memory for the copies. It's not great, but there's no accessibility errors... I'm not sure if I ought to use Unchecked_Deallocate and/or Finalize here though. (Also, pools might be nice to ensure that things really do get cleaned up upon scope-exit.)

-- In the Spec:
------------------------------------
    Function Create (
		    Location_Name : String; -- Unique ID-string
		    North, South, East, West,
		    Up, Down : Story_Location'Class:= Nowhere
		    ) return Story_Location;

-- In the Body:
------------------------------------
    Function Create (
		    Location_Name : String;
		    North, South, East, West,
		    Up, Down : Maze'Class:= None
		    ) return Maze is
	
	N : Maze renames Maze(North);
	S : Maze renames Maze(South);
	E : Maze renames Maze(East);
	W : Maze renames Maze(West);
	U : Maze renames Maze(Up);
	D : Maze renames Maze(Down);
	
	Subtype Node is Maze( Length_N => Location_Name'Length );
    begin
	    Return Result : Node do
	    Result.Name := Location_Name;
	    Result.Exits:=
		(
		   Maze.North =>
		     (if N = Nowhere then null else New Maze'( N )),
		   Maze.South =>
		     (if S = Nowhere then null else New Maze'( S )),
		   Maze.East =>
		     (if E = Nowhere then null else New Maze'( E )),
		   Maze.West =>
		     (if W = Nowhere then null else New Maze'( W )),
		   Maze.Up => 
		     (if U = Nowhere then null else New Maze'( U )),
		   Maze.Down =>
		     (if D = Nowhere then null else New Maze'( D )),
		   others => null
		);
	End return;
    end;


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-20  6:29           ` Shark8
@ 2013-10-20 15:33             ` sbelmont700
  2013-10-21  0:29               ` Shark8
  0 siblings, 1 reply; 11+ messages in thread
From: sbelmont700 @ 2013-10-20 15:33 UTC (permalink / raw)


As long as you are onto the heap anyway, why not just make the client create the array (with items on the heap) save a reference to that, and avoid all the headaches?

type Paths is array (Positive range <>) of Maze_Ptr;

type Maze (p : access constant Paths) is ...

function Create (x : aliased Paths) is
begin
   return Maze'(p => x'access);
end Create;

The use case I would like is essentially this, with some magic feature that lets you satisfy the accessibility check for local values since the code is obviously not creating dangling pointers.  After all, you can pass pointers safely by themselves (access parameters) and nested within a record (access discriminant), so there ought to be some mechanism that allows you to pass them around safely within an array, if for no other reason that consistency.

-sb


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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-20 15:33             ` sbelmont700
@ 2013-10-21  0:29               ` Shark8
  2013-10-21  0:55                 ` sbelmont700
  0 siblings, 1 reply; 11+ messages in thread
From: Shark8 @ 2013-10-21  0:29 UTC (permalink / raw)


On Sunday, October 20, 2013 9:33:15 AM UTC-6, sbelm...@gmail.com wrote:
> As long as you are onto the heap anyway, why not just make the client create the array (with items on the heap) save a reference to that, and avoid all the headaches?

For what I'm doing the main use-case is reading from a text-file, building the structures, and passing that out to some game-"engine"/interface. -- I just wanted/needed a way to create the objects programatically to ensure the read/write are correct, and it seemed odd that the aliased parameters weren't working as expected.

> The use case I would like is essentially this, with some magic feature that lets you satisfy the accessibility check for local values since the code is obviously not creating dangling pointers.  After all, you can pass pointers safely by themselves (access parameters) and nested within a record (access discriminant), so there ought to be some mechanism that allows you to pass them around safely within an array, if for no other reason that consistency.

Interesting; I _think_ the reason that the access-discriminant works is that the record itself has a deeper level than the access, thus when the record leaves scope the access may or may not be viable: the access could have the same scope as the record, or the record nested inside the scope declaring the access.

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

* Re: Possible GNAT problem with aliased parameters.
  2013-10-21  0:29               ` Shark8
@ 2013-10-21  0:55                 ` sbelmont700
  0 siblings, 0 replies; 11+ messages in thread
From: sbelmont700 @ 2013-10-21  0:55 UTC (permalink / raw)


On Sunday, October 20, 2013 8:29:36 PM UTC-4, Shark8 wrote:

> Interesting; I _think_ the reason that the access-discriminant works is that the record itself has a deeper level than the access, thus when the record leaves scope the access may or may not be viable: the access could have the same scope as the record, or the record nested inside the scope declaring the access.

FWIT, there is a run-time check to be aware of when returning objects with access discriminants in this way, for instance if the aliased parameter is on the heap but the return object is not.

-sb

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

end of thread, other threads:[~2013-10-21  0:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-18 16:01 Possible GNAT problem with aliased parameters Shark8
2013-10-18 16:51 ` sbelmont700
2013-10-19  1:59   ` Randy Brukardt
2013-10-19  5:48     ` Shark8
2013-10-19  7:48       ` Dmitry A. Kazakov
2013-10-19 14:30       ` sbelmont700
2013-10-19 21:17         ` Shark8
2013-10-20  6:29           ` Shark8
2013-10-20 15:33             ` sbelmont700
2013-10-21  0:29               ` Shark8
2013-10-21  0:55                 ` sbelmont700

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