comp.lang.ada
 help / color / mirror / Atom feed
* How to pass around access types to interfaces?
@ 2008-10-24 11:45 Sven
  2008-10-24 12:24 ` Niklas Holsti
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Sven @ 2008-10-24 11:45 UTC (permalink / raw)


I'm learning Ada and I've run into a big problem with passing around
access types to interfaces. I guess I just don't know all the
subtleties of access types, I'm used to C/C++ pointers. I didn't find
anything helpful on the net or in the  Ada Reference Manual.

I'm trying to get this code to run:

in some package:
  type My_Interface is interface;
  type My_Interface_Access is access all My_Interface'Class;

  procedure Do_Something( Item : in out Some_Object; With :
My_Interface_Access );

in main program:
  type Concrete_Type is new My_Interface with ...;


I need to pass an object of type Concrete_Type to the With parameter
of the Do_Something procedure. But the Compiler won't let me, no
matter what I do.


   My_Object : access Concrete_Type := new Concrete_Type;
   Do_Something( Item, My_Interface_Access( My_Object ) );

gives the compiler error "cannot convert local pointer to non-local
access type".

   My_Object : My_Interface_Access := new Concrete_Type;

gives the compiler error "type in allocator has deeper level than
designated class-wide type".

I found a way to pass my paramter by using this function:

  function Convert( Item : not null access Concrete_Type ) return
My_Interface_Access is
  begin
    return My_Interface_Access( Item );
  end;

But I don't this is such a good idea.

What is the right way to do this? I can't imagine that what I'm trying
to do is not supported in Ada.



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

* Re: How to pass around access types to interfaces?
  2008-10-24 11:45 How to pass around access types to interfaces? Sven
@ 2008-10-24 12:24 ` Niklas Holsti
  2008-10-24 12:49   ` Sven
  2008-10-24 21:32 ` sjw
  2008-10-25 15:43 ` Martin Krischik
  2 siblings, 1 reply; 16+ messages in thread
From: Niklas Holsti @ 2008-10-24 12:24 UTC (permalink / raw)


Sven wrote:
> I'm learning Ada and I've run into a big problem with passing around
> access types to interfaces. I guess I just don't know all the
> subtleties of access types, I'm used to C/C++ pointers. I didn't find
> anything helpful on the net or in the  Ada Reference Manual.
> 
> I'm trying to get this code to run:
> 
> in some package:
>   type My_Interface is interface;
>   type My_Interface_Access is access all My_Interface'Class;
> 
>   procedure Do_Something( Item : in out Some_Object; With :
> My_Interface_Access );
> 
> in main program:
>   type Concrete_Type is new My_Interface with ...;

I assume this type declaration is in the main *procedure*. This 
means that the type has a local scope and life, which prevents 
converting its values to a more long-lived access type. Try 
declaring Concrete_Type in a package; that makes it live as long as 
the whole program, and should allow such conversions.

HTH,

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: How to pass around access types to interfaces?
  2008-10-24 12:24 ` Niklas Holsti
@ 2008-10-24 12:49   ` Sven
  2008-10-24 13:55     ` Ludovic Brenta
  0 siblings, 1 reply; 16+ messages in thread
From: Sven @ 2008-10-24 12:49 UTC (permalink / raw)


> I assume this type declaration is in the main *procedure*. This
> means that the type has a local scope and life, which prevents
> converting its values to a more long-lived access type. Try
> declaring Concrete_Type in a package; that makes it live as long as
> the whole program, and should allow such conversions.

Yeah, the declaration was in the main procedure. When moving it to a
package everything works like it's supposed to. Thanks for your help.

I guess I have still a lot to learn about Ada. I was just thinking
about the lifetime of the object. It never occured to me that a type
also has a lifetime.



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

* Re: How to pass around access types to interfaces?
  2008-10-24 12:49   ` Sven
@ 2008-10-24 13:55     ` Ludovic Brenta
  0 siblings, 0 replies; 16+ messages in thread
From: Ludovic Brenta @ 2008-10-24 13:55 UTC (permalink / raw)


> > I assume this type declaration is in the main *procedure*. This
> > means that the type has a local scope and life, which prevents
> > converting its values to a more long-lived access type. Try
> > declaring Concrete_Type in a package; that makes it live as long as
> > the whole program, and should allow such conversions.
>
> Yeah, the declaration was in the main procedure. When moving it to a
> package everything works like it's supposed to. Thanks for your help.
>
> I guess I have still a lot to learn about Ada. I was just thinking
> about the lifetime of the object. It never occured to me that a type
> also has a lifetime.

This is one of the most complex areas of Ada; it defines the lifetime
of both objects and types in terms of "accessibility levels" (RM
3.10.2). This explains the error message "type in allocator has deeper
level than designated class-wide type".

Types can have a limited life time since they can be declared inside a
subprogram (or indeed in any block).

--
Ludovic Brenta.



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

* Re: How to pass around access types to interfaces?
  2008-10-24 11:45 How to pass around access types to interfaces? Sven
  2008-10-24 12:24 ` Niklas Holsti
@ 2008-10-24 21:32 ` sjw
  2008-10-25  8:54   ` Sven
  2008-10-25 15:43 ` Martin Krischik
  2 siblings, 1 reply; 16+ messages in thread
From: sjw @ 2008-10-24 21:32 UTC (permalink / raw)


On Oct 24, 12:45 pm, Sven <sven.weida...@gmail.com> wrote:
> I'm trying to get this code to run:
>
> in some package:
>   type My_Interface is interface;
>   type My_Interface_Access is access all My_Interface'Class;
>
>   procedure Do_Something( Item : in out Some_Object; With :
> My_Interface_Access );

Does your compiler let you use the reserved word 'with' as the name of
a parameter? That could confuse things ..



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

* Re: How to pass around access types to interfaces?
  2008-10-24 21:32 ` sjw
@ 2008-10-25  8:54   ` Sven
  0 siblings, 0 replies; 16+ messages in thread
From: Sven @ 2008-10-25  8:54 UTC (permalink / raw)


On 24 Okt., 23:32, sjw <simon.j.wri...@mac.com> wrote:
> On Oct 24, 12:45 pm, Sven <sven.weida...@gmail.com> wrote:
>
> > I'm trying to get this code to run:
>
> > in some package:
> >   type My_Interface is interface;
> >   type My_Interface_Access is access all My_Interface'Class;
>
> >   procedure Do_Something( Item : in out Some_Object; With :
> > My_Interface_Access );
>
> Does your compiler let you use the reserved word 'with' as the name of
> a parameter? That could confuse things ..

I guess not. My real code looks different, I just made those names up
to show what my problem is. That was easier than to strip down my
actual code to just the problem.



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

* Re: How to pass around access types to interfaces?
  2008-10-24 11:45 How to pass around access types to interfaces? Sven
  2008-10-24 12:24 ` Niklas Holsti
  2008-10-24 21:32 ` sjw
@ 2008-10-25 15:43 ` Martin Krischik
  2008-10-25 22:15   ` Robert A Duff
  2008-10-29 12:42   ` Sven
  2 siblings, 2 replies; 16+ messages in thread
From: Martin Krischik @ 2008-10-25 15:43 UTC (permalink / raw)


Am 24.10.2008, 13:45 Uhr, schrieb Sven <sven.weidauer@gmail.com>:

>   type My_Interface_Access is access all My_Interface'Class;

Do you realy need an access type? Read:

http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#The_class-wide_type

If so, does it need to be an access all? Read:

http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Access_vs._access_all

Six month after I switched from C++ to Ada I removed about 80% access  
types from the code I created until then. And from those access types  
which remained more did not need the "all" and I consequently removed that  
as well.

Martin
-- 
Martin Krischik



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

* Re: How to pass around access types to interfaces?
  2008-10-25 15:43 ` Martin Krischik
@ 2008-10-25 22:15   ` Robert A Duff
  2008-10-26  8:02     ` Dmitry A. Kazakov
  2008-10-26 15:50     ` Martin Krischik
  2008-10-29 12:42   ` Sven
  1 sibling, 2 replies; 16+ messages in thread
From: Robert A Duff @ 2008-10-25 22:15 UTC (permalink / raw)


"Martin Krischik" <krischik@users.sourceforge.net> writes:

> Am 24.10.2008, 13:45 Uhr, schrieb Sven <sven.weidauer@gmail.com>:
>
>>   type My_Interface_Access is access all My_Interface'Class;
>
> Do you realy need an access type? Read:
>
> http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#The_class-wide_type
>
> If so, does it need to be an access all? Read:

In my experience, access-to-class-wide types almost always need to have
"all", because you often want to convert from access-to-T2 up to
access-to-T1'Class (where T2 is a descendant of T1).

- Bob



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

* Re: How to pass around access types to interfaces?
  2008-10-25 22:15   ` Robert A Duff
@ 2008-10-26  8:02     ` Dmitry A. Kazakov
  2008-10-26 15:50     ` Martin Krischik
  1 sibling, 0 replies; 16+ messages in thread
From: Dmitry A. Kazakov @ 2008-10-26  8:02 UTC (permalink / raw)


On Sat, 25 Oct 2008 18:15:09 -0400, Robert A Duff wrote:

> "Martin Krischik" <krischik@users.sourceforge.net> writes:
> 
>> Am 24.10.2008, 13:45 Uhr, schrieb Sven <sven.weidauer@gmail.com>:
>>
>>>   type My_Interface_Access is access all My_Interface'Class;
>>
>> Do you realy need an access type? Read:
>>
>> http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#The_class-wide_type
>>
>> If so, does it need to be an access all? Read:
> 
> In my experience, access-to-class-wide types almost always need to have
> "all", because you often want to convert from access-to-T2 up to
> access-to-T1'Class (where T2 is a descendant of T1).

It would be nice if that were finally fixed! [*]

But, in general it is better to use only access to class-wide. So the cases
where access to T2 is converted to access to T1 are suspicious to me. When
that happens I readily use Unchecked_Conversion, since it is already
broken.

--------
*  Similar issue: there is no good way to obtain a pool-specific access
type from Finalize.

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



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

* Re: How to pass around access types to interfaces?
  2008-10-25 22:15   ` Robert A Duff
  2008-10-26  8:02     ` Dmitry A. Kazakov
@ 2008-10-26 15:50     ` Martin Krischik
  2008-10-28 13:41       ` Maciej Sobczak
  1 sibling, 1 reply; 16+ messages in thread
From: Martin Krischik @ 2008-10-26 15:50 UTC (permalink / raw)


Am 26.10.2008, 00:15 Uhr, schrieb Robert A Duff  
<bobduff@shell01.theworld.com>:

> "Martin Krischik" <krischik@users.sourceforge.net> writes:
>
>> Am 24.10.2008, 13:45 Uhr, schrieb Sven <sven.weidauer@gmail.com>:
>>
>>>   type My_Interface_Access is access all My_Interface'Class;
>>
>> Do you realy need an access type? Read:
>>
>> http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#The_class-wide_type
>>
>> If so, does it need to be an access all? Read:
>
> In my experience, access-to-class-wide types almost always need to have
> "all", because you often want to convert from access-to-T2 up to
> access-to-T1'Class (where T2 is a descendant of T1).

I guess you are right here. But then: access to class wide is the kind of  
access which a C++ convert will uses without realy needing them. I should  
know, I am a C++ convert who made precisely that mistake.

Martin

-- 
Martin Krischik



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

* Re: How to pass around access types to interfaces?
  2008-10-26 15:50     ` Martin Krischik
@ 2008-10-28 13:41       ` Maciej Sobczak
  2008-10-29 14:15         ` Martin Krischik
  0 siblings, 1 reply; 16+ messages in thread
From: Maciej Sobczak @ 2008-10-28 13:41 UTC (permalink / raw)


On 26 Paź, 16:50, "Martin Krischik" <krisc...@users.sourceforge.net>
wrote:

> But then: access to class wide is the kind of  
> access which a C++ convert will uses without realy needing them. I should  
> know, I am a C++ convert who made precisely that mistake.

It might depend on what you did in C++ before converting. ;-)
Since most of the code does not need pointers anyway, the frequent
idiom is to pass objects by reference (likely to the base class),
something like:

void foo(const SomeClass & object);

I don't see how moving this to Ada can lead one to use pointers -
personally, I find "in Some_Type'Class" to be very natural. No
pointers needed.

I think that in the above context what is *really* dangerous and
difficult to clean up is the C background, not C++. Unfortunately the
former one prevails.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: How to pass around access types to interfaces?
  2008-10-25 15:43 ` Martin Krischik
  2008-10-25 22:15   ` Robert A Duff
@ 2008-10-29 12:42   ` Sven
  2008-10-29 13:17     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 16+ messages in thread
From: Sven @ 2008-10-29 12:42 UTC (permalink / raw)


On 25 Okt., 16:43, "Martin Krischik" <krisc...@users.sourceforge.net>
wrote:
> Am 24.10.2008, 13:45 Uhr, schrieb Sven <sven.weida...@gmail.com>:
>
> >   type My_Interface_Access is access all My_Interface'Class;
>
> Do you realy need an access type? Read:
>
> http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#The_c...

Yes, this needs to be an access type. I need to store references to an
object, not the object itself. As far as I understand Ada this can
only be done via access types. Declaring a record member of type
"My_Interface'Class" is not possible. But even if it was it would
store a copy of the object, which would be incorrect and a waste of
memory.

> If so, does it need to be an access all? Read:
>
> http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Access_vs._...
>
> Six month after I switched from C++ to Ada I removed about 80% access  
> types from the code I created until then. And from those access types  
> which remained more did not need the "all" and I consequently removed that  
> as well.

"Access all" will allow me to pass references to aliased objects.
Right now there is no reason to disallow that, so I'll keep the "all".



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

* Re: How to pass around access types to interfaces?
  2008-10-29 12:42   ` Sven
@ 2008-10-29 13:17     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry A. Kazakov @ 2008-10-29 13:17 UTC (permalink / raw)


On Wed, 29 Oct 2008 05:42:38 -0700 (PDT), Sven wrote:

> "Access all" will allow me to pass references to aliased objects.
> Right now there is no reason to disallow that, so I'll keep the "all".

It is unrelated to being aliased. Limited tagged objects are aliased
anyway. (It usually makes no sense to reference non-limited ones).

"Access all" means that the pointer can point anywhere. Plain "access"
means that it can point only to the storage pool of the access type. The
memory pool can be specified explicitly using "for P'Storage_Pool use ..."

--------------
Rant:

My rule of thumb is that an explicitly declared access type is always
pool-specific in absence of further requirements. This is especially
important when the type is a formal generic parameter. Furthermore, in Ada
2005, which has by-structure matched anonymous access types, I see no
obvious reason to declare general access types ("access all") at all. It
seems to me that in all cases where general access comes in question, the
access type can be anonymous.

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



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

* Re: How to pass around access types to interfaces?
  2008-10-28 13:41       ` Maciej Sobczak
@ 2008-10-29 14:15         ` Martin Krischik
  2008-10-31 13:38           ` Maciej Sobczak
  0 siblings, 1 reply; 16+ messages in thread
From: Martin Krischik @ 2008-10-29 14:15 UTC (permalink / raw)


Maciej Sobczak schrieb:
> On 26 Paź, 16:50, "Martin Krischik" <krisc...@users.sourceforge.net>
> wrote:
> 
>> But then: access to class wide is the kind of  
>> access which a C++ convert will uses without realy needing them. I should  
>> know, I am a C++ convert who made precisely that mistake.
> 
> It might depend on what you did in C++ before converting. ;-)
> Since most of the code does not need pointers anyway, the frequent
> idiom is to pass objects by reference (likely to the base class),
> something like:
> 
> void foo(const SomeClass & object);

Not the function call is the problem - the creation and storage of
objects is.

For example: now are you going to fill a vector<base_class&> with
objects? And how do you delete those objects again? This is where C++ lags.

In Ada we have Ada.Container.Indefinite_Vector which can hold Base'Class
objects. (Remember that is was me who requested the inclusion of
Ada.Container.Indefinite_Vector into the standard. It was also me who
created BC.Indefinite_Containers)

> I think that in the above context what is *really* dangerous and
> difficult to clean up is the C background, not C++. Unfortunately the
> former one prevails.

Well I did C before C++ and Modula-2 before that and Pascal before that.

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



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

* Re: How to pass around access types to interfaces?
  2008-10-29 14:15         ` Martin Krischik
@ 2008-10-31 13:38           ` Maciej Sobczak
  2008-10-31 14:46             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 16+ messages in thread
From: Maciej Sobczak @ 2008-10-31 13:38 UTC (permalink / raw)


On 29 Paź, 15:15, Martin Krischik <krisc...@users.sourceforge.net>
wrote:

> Not the function call is the problem - the creation and storage of
> objects is.
>
> For example: now are you going to fill a vector<base_class&> with
> objects?

This:

vector<shared_ptr<base_class> >

or this:

http://www.boost.org/doc/libs/1_36_0/libs/ptr_container/doc/ptr_container.html

> And how do you delete those objects again?

It's automagic.

> This is where C++ lags.

No, this is not a language issue - it is the question of standard
library completeness. In this aspect both Ada and C++ lag terribly.

I have to admit, though, that in the area of OO Ada solves one problem
in a way that is really excellent - it has the ability to create and
return Base'Class from a factory function without explicitly involving
dynamic memory (extended return makes it even nicer).
C++ cannot do that.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: How to pass around access types to interfaces?
  2008-10-31 13:38           ` Maciej Sobczak
@ 2008-10-31 14:46             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry A. Kazakov @ 2008-10-31 14:46 UTC (permalink / raw)


On Fri, 31 Oct 2008 06:38:17 -0700 (PDT), Maciej Sobczak wrote:

> On 29 Paďż˝, 15:15, Martin Krischik <krisc...@users.sourceforge.net>
> wrote:
> 
>> This is where C++ lags.
> 
> No, this is not a language issue - it is the question of standard
> library completeness.

These libraries cannot be complete because of certain language issues. In
order to have containers of copyable polymorphic objects you need a
polymorphic copy.

> In this aspect both Ada and C++ lag terribly.

Historically C++ has evolved to meet needs of the designers of STL.
Unfortunately they did not much care about the language itself. One could
argue that same happened to Ada 2005.

The languages lag not in libraries, they do in their types systems exposed
to numerous problems. An inability to have simple container types of
polymorphic elements is merely a consequence of these problems.

Yes you could workaround many of these problems with pointers, which is in
the core of all proposals.

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



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

end of thread, other threads:[~2008-10-31 14:46 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-24 11:45 How to pass around access types to interfaces? Sven
2008-10-24 12:24 ` Niklas Holsti
2008-10-24 12:49   ` Sven
2008-10-24 13:55     ` Ludovic Brenta
2008-10-24 21:32 ` sjw
2008-10-25  8:54   ` Sven
2008-10-25 15:43 ` Martin Krischik
2008-10-25 22:15   ` Robert A Duff
2008-10-26  8:02     ` Dmitry A. Kazakov
2008-10-26 15:50     ` Martin Krischik
2008-10-28 13:41       ` Maciej Sobczak
2008-10-29 14:15         ` Martin Krischik
2008-10-31 13:38           ` Maciej Sobczak
2008-10-31 14:46             ` Dmitry A. Kazakov
2008-10-29 12:42   ` Sven
2008-10-29 13:17     ` Dmitry A. Kazakov

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