comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Private primitive operations available to entire package hierarchy. Can it be done?
Date: Thu, 28 Jul 2005 19:40:58 -0500
Date: 2005-07-28T19:40:58-05:00	[thread overview]
Message-ID: <OeOdneQx2-z953TfRVn-vw@megapath.net> (raw)
In-Reply-To: 1122545378.984920.272260@g47g2000cwa.googlegroups.com

"Lucretia" <lucretia9@lycos.co.uk> wrote in message
news:1122545378.984920.272260@g47g2000cwa.googlegroups.com...
...
>>> and having all primitives take an access parameter as the controlling
>>> parameter.

>>That's awful. If you do that, you're requiring your user to do memory
management
>>for you, rather than the other way around. They'll be forced into subpar
syntax
>>(explicit uses of aliased and 'Access), have runtime accessibility errors,
and
>>other nastyness. And they would have no way to use the containers library
>>do the storage management for them.

>What's awful? Using access parameters as the controlling type or just
>using instances the way I have been doing?

Using access types in the user interface. I believe that they should be
limited to cases where there is no other choice (generally because of
copying issues).

> I don't really see what you mean about forcing the user into handling
> the memory management. subpar syntax? Dunno what that means :-/

If you use access types in the parameters, then the users of your interface
will have to either:

* use an allocator (new) to create objects. In that case, they'll have to
use Unchecked_Deallocation to get rid of them. That puts a lot of effort on
the user that they may not need the power of (often stack allocation is just
fine for objects); or
* declare objects with the ugly "aliased" syntax, and worse, have to use the
'Unchecked_Access attribute in most calls. Which means a lot of extra typing
(and more importantly, reading) that has nothing to do with their program.

Moreover, if you use access types in this way, you're preventing the users
from using an Ada.Containers container to do their memory management. They'd
have to put access values into the container, and do their own memory
management on those values -- pretty much defeating the purpose of a
container.

There is also the issue of accessibility; you can get runtime failures if
user pass 'Access of a local object and you want to store that into some
library-level type (even for immediate, short-term use).

In Ada 95, you can't pass null, either, so even that tiny utility is not
available.

My motto is to let the user of my libraries to determine the memory
management most appropriate for their uses, and that means passing objects,
not access values. Given Ada's rules, the generated code is the same either
way anyway - indeed, object passing is likely to be cheaper (no
accessibility level to pass). Just say no to anonymous access parameters.
:-) [Personally, I believe that anonymous access types were a complete
mistake; the only issue was missing "in out" parameters for functions. There
is no technical advantage to using anonymous access types in any situation,
and many pitfalls.]

<quote>
And the implementation of Add:


    procedure Add (Sizer : Sizer_Type; Button : Button_Type'Class) is
         My_Button : Any_Button_Access_Type := Button'Unchecked_Access;

         My_Sizer : Any_Sizer_Access_Type := Sizer'Unchecked_Access;
    begin
         -- Call the low level (C) routines:
         wx_Add (My_Sizer, My_Button);
         -- etc.
    end Add;

You might need to do some type conversions on the access types, but
that's
</quote>

> I thought that it was considered bad to get the access of a parameter
> in this way?

I sure hope not, its the central tenet of the Claw design. It *is* necessary
to be careful about lifetime issues. There is nothing to worry about if the
access value will not be used any longer than the duration of the call - the
parameter cannot be finalized while the call is active (unless the program
is erroneous anyway - it would probably crash for reasons having nothing to
do with your library if that happened). If you need to use it longer, then
you have to make sure that you have a way to destroy the access value if the
object gets finalized while you are still holding onto the access value.
Claw uses controlled types for this; when an object is finalized, the object
is removed from all lists and other objects that it is in (obviously, that
means making sure that the object keeps track of every place that it is
linked).

Note that these issues are exactly the same if you use access types. The
only difference is that you might get a runtime failure if the user used
'Access instead of 'Unchecked_Access. (By doing this in your own code, you
can avoid having to require your users to use 'Unchecked_Access for their
calls to work reliably.)

                                       Randy.






  reply	other threads:[~2005-07-29  0:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-07-07 16:06 Private primitive operations available to entire package hierarchy. Can it be done? Lucretia
2005-07-07 16:17 ` OT: Joke Adrien Plisson
2005-07-07 16:24   ` Matthew Heaney
2005-07-07 19:10 ` Private primitive operations available to entire package hierarchy. Can it be done? Randy Brukardt
2005-07-13 15:40   ` Lucretia
2005-07-19 23:19     ` Randy Brukardt
2005-07-20 18:14       ` Lucretia
2005-07-21  3:10         ` Randy Brukardt
2005-07-25 18:14           ` Lucretia
2005-07-25 23:58             ` Randy Brukardt
2005-07-27 17:36               ` Lucretia
2005-07-27 21:28                 ` Randy Brukardt
2005-07-28 10:09                   ` Lucretia
2005-07-29  0:40                     ` Randy Brukardt [this message]
2005-08-02 15:55                       ` Lucretia
2005-08-03 18:26                         ` Lucretia
2005-08-03 20:04                           ` Randy Brukardt
2005-08-03 20:03                         ` Randy Brukardt
2005-08-08 18:04                           ` Lucretia
2005-08-08 20:47                             ` Randy Brukardt
replies disabled

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