comp.lang.ada
 help / color / mirror / Atom feed
* memory management in Ada: tedious without GC?
@ 2008-05-16 17:44 jhc0033
  2008-05-16 18:56 ` Ludovic Brenta
                   ` (5 more replies)
  0 siblings, 6 replies; 70+ messages in thread
From: jhc0033 @ 2008-05-16 17:44 UTC (permalink / raw)


I'm mostly soliciting answers from Ada programmers who know C++ RAII
well (Skip this if you use the words "C" and "C++" interchangeably,
please. Your answers will be misleading at best):

As I understood from reading the Memory Management section of
Wikibooks on Ada, Ada's memory management facilities are roughly
equivalent to

a. C++-like "new"
b. C++-like "delete"
c. Java-like "finally"
d. your implementation may or may not have GC

Did I misunderstand?

To me, this seems much, much more error-prone and tedious that C++'s
RAII approach, where you almost never have to worry about deallocation
(i.e. "b" and "c" above), even in the presence of exceptions, unless
you have GC. Besides, RAII applies to a bunch of other things, like
thread locks, database connections, files - not just memory.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
@ 2008-05-16 18:56 ` Ludovic Brenta
  2008-05-16 20:42 ` Maciej Sobczak
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 70+ messages in thread
From: Ludovic Brenta @ 2008-05-16 18:56 UTC (permalink / raw)


"jhc0033@gmail.com" <jhc0033@gmail.com> writes:

> I'm mostly soliciting answers from Ada programmers who know C++ RAII
> well (Skip this if you use the words "C" and "C++" interchangeably,
> please. Your answers will be misleading at best):
>
> As I understood from reading the Memory Management section of
> Wikibooks on Ada, Ada's memory management facilities are roughly
> equivalent to
>
> a. C++-like "new"
> b. C++-like "delete"
> c. Java-like "finally"
> d. your implementation may or may not have GC
>
> Did I misunderstand?

No, but you didn't get the entire picture.

> To me, this seems much, much more error-prone and tedious that C++'s
> RAII approach, where you almost never have to worry about deallocation
> (i.e. "b" and "c" above), even in the presence of exceptions, unless
> you have GC. Besides, RAII applies to a bunch of other things, like
> thread locks, database connections, files - not just memory.

Read up on "controlled types" and, in the ARM, on Ada.Finalization, as
well as "storage pools".  That will complete your understanding of
Ada's memory management.

-- 
Ludovic Brenta.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
  2008-05-16 18:56 ` Ludovic Brenta
@ 2008-05-16 20:42 ` Maciej Sobczak
  2008-05-16 21:45   ` Ivan Levashew
                     ` (3 more replies)
  2008-05-16 22:45 ` anon
                   ` (3 subsequent siblings)
  5 siblings, 4 replies; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-16 20:42 UTC (permalink / raw)


On 16 Maj, 19:44, "jhc0...@gmail.com" <jhc0...@gmail.com> wrote:

> As I understood from reading the Memory Management section of
> Wikibooks on Ada, Ada's memory management facilities are roughly
> equivalent to
>
> a. C++-like "new"

Yes, you can do this in Ada.

> b. C++-like "delete"

Yes, you can do this in Ada, but it is discouraged by the awful syntax
and actually rarely needed.

> c. Java-like "finally"

I don't see any equivalent to "finally" in Ada - and, as in C++, it is
not needed, since a superior tool is available: RAII.

> d. your implementation may or may not have GC

Just as in C++. In practice and for portability it means: assume there
is no GC.

> Did I misunderstand?

Actually, Ada and C++ are very similar in this regard and Java differs
widely from these two.

> To me, this seems much, much more error-prone and tedious that C++'s
> RAII approach

In Ada RAII is realized with controlled types. They are severely
broken in that they are intrusive in the type hierarchy and they burn
the whole budget for implementation inheritance, which is a big issue
with the lack of multiple inheritance (controlled streams, anyone?) -
these problems don't exist in C++ - but apart from that both Ada and C+
+ represent a similar approach to resource management. You *can* have
RAII-enabled files, database sessions, smart pointers, and so on.

Note that Ada, even though provides the possibility to use RAII when
designing types, does not benefit from it everywhere in its standard
library.

> where you almost never have to worry about deallocation
> (i.e. "b" and "c" above), even in the presence of exceptions, unless
> you have GC.

> Besides, RAII applies to a bunch of other things, like
> thread locks, database connections, files - not just memory.

That's why GC should not stop you from worrying about resources (and
if you still have to worry, then what's the fuss?). The above are
resources, which are not correctly addressed by GC as you know it from
Java.
Compared to this, RAII is a more uniform framework for handling
resources *in general* and both Ada and C++ support it.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 20:42 ` Maciej Sobczak
@ 2008-05-16 21:45   ` Ivan Levashew
  2008-05-16 22:59   ` Peter C. Chapin
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 70+ messages in thread
From: Ivan Levashew @ 2008-05-16 21:45 UTC (permalink / raw)


Maciej Sobczak пишет:
> which is a big issue with the lack of multiple inheritance
Mix-ins, no?

http://www.gidenstam.org/Ada/
Ada Add Finalization Anywhere Library mixes-in special Controlled object.

But, anyway, I think it's usually possible to localize what's really 
needing finalization and make this internal object controlled not the 
whole parent object.

-- 
If you want to get to the top, you have to start at the bottom



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
  2008-05-16 18:56 ` Ludovic Brenta
  2008-05-16 20:42 ` Maciej Sobczak
@ 2008-05-16 22:45 ` anon
  2008-05-17  7:34 ` Pascal Obry
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 70+ messages in thread
From: anon @ 2008-05-16 22:45 UTC (permalink / raw)


        Ada is design for creating a hard optimized Ada partition (program) 
that uses no GC. In a true optimized partition the "New" function should be 
only used in the initialization stage and the "Deallocation" (free) function 
during the finalization stage. In this design the programmer can create 
their own memory management package that is needed by the partition 
which can be optimized to fit the needs of the execution of that 
partition. This way the partition does not have to wait for memory 
resources from the OS or other programs. The exception is memory page 
swapping which can be controlled by the partition in some cases.

        As for being error-prone, the answer is no.  The partition request 
all of the needed memory before it continues with the execution. In this 
way the Ada run-time system knows that it has the memory necessary for 
the execution of the partition . It might seam to be wasteful, but a hard 
optimized partition only waste a small amount of memory. The unused part 
of the allocated memory block. 


        Also, forget "C++  like" design structure it design from "C".  Ada 
and most other compilers are written using the C libraries structures not 
"C++ like".  But for some reason a lot of "C++" programmers are trying to 
alter the facts and saying "C++" instead of C. Also, the Java low-level 
routines are written in C as well. 


In <4ddef8bf-b5b1-4d7e-b75b-386cd6c8402c@l17g2000pri.googlegroups.com>, "jhc0033@gmail.com" <jhc0033@gmail.com> writes:
>I'm mostly soliciting answers from Ada programmers who know C++ RAII
>well (Skip this if you use the words "C" and "C++" interchangeably,
>please. Your answers will be misleading at best):
>
>As I understood from reading the Memory Management section of
>Wikibooks on Ada, Ada's memory management facilities are roughly
>equivalent to
>
>a. C++-like "new"
>b. C++-like "delete"
>c. Java-like "finally"
>d. your implementation may or may not have GC
>
>Did I misunderstand?
>
>To me, this seems much, much more error-prone and tedious that C++'s
>RAII approach, where you almost never have to worry about deallocation
>(i.e. "b" and "c" above), even in the presence of exceptions, unless
>you have GC. Besides, RAII applies to a bunch of other things, like
>thread locks, database connections, files - not just memory.




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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 20:42 ` Maciej Sobczak
  2008-05-16 21:45   ` Ivan Levashew
@ 2008-05-16 22:59   ` Peter C. Chapin
  2008-05-17  5:24     ` jhc0033
  2008-05-16 23:05   ` Randy Brukardt
  2008-05-19  3:50   ` Matthew Heaney
  3 siblings, 1 reply; 70+ messages in thread
From: Peter C. Chapin @ 2008-05-16 22:59 UTC (permalink / raw)


Maciej Sobczak wrote:

> In Ada RAII is realized with controlled types.

Controlled types in Ada are great, but I think C++ has a bit of an edge 
in this area (not considering the issue of the type hierarchy). In Ada, 
the compiler calls Adjust after it has finalized the object on the left 
side of an assignment. In C++ operator=() has access to both sides of 
the assignment at once. This makes it easier to write exception safe 
assignment operators by copying the state of the source object *before* 
destroying the target. It doesn't seem like that's possible with Ada 
controlled types.

I've worked around this by declaring such types limited, using 
Limited_Controlled, and living without a user defined assignment 
operation. This seems to be a feasible way to handle the situation, 
especially in Ada 2005 which allows functions to return limited types.

Anyway, to the OP... yes, RAII is available in Ada although the precise 
details of how to set it up are a bit different than in C++. Be aware 
that Ada uses the word "finalize" differently than the way it is used in 
the Java community. In Ada finialization is more like C++ destruction. 
It is deterministic.

Peter



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 20:42 ` Maciej Sobczak
  2008-05-16 21:45   ` Ivan Levashew
  2008-05-16 22:59   ` Peter C. Chapin
@ 2008-05-16 23:05   ` Randy Brukardt
  2008-05-19  3:50   ` Matthew Heaney
  3 siblings, 0 replies; 70+ messages in thread
From: Randy Brukardt @ 2008-05-16 23:05 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message 
news:9f2c2db4-d6c1-4cdf-884c-5cbc26ac7701@d1g2000hsg.googlegroups.com...
...
> In Ada RAII is realized with controlled types. They are severely
> broken in that they are intrusive in the type hierarchy and they burn
> the whole budget for implementation inheritance, which is a big issue
> with the lack of multiple inheritance (controlled streams, anyone?) -
...

I understand your point, but I think it is wrong. That's because I think all 
new tagged types should be controlled types (even if you are not using the 
functionality now). If you have a non-formal parameter type "type T is 
tagged..." you are guilty of premature optimization. (Yes, I can imagine 
that there exist cases where the overhead is too much, but I think you need 
to prove that in practice before worrying about -- it surely is possible for 
compilers to eliminate the overhead of unused initialization/finalization, 
and most do to some degree.)

If you get stuck with badly designed existing types, you can wrap the new 
stuff in a controlled type and get the correct behavior (as someone else 
suggested). (It's very rare that implementation inheritance buys you 
anything anyway.)

                                                Randy.





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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 22:59   ` Peter C. Chapin
@ 2008-05-17  5:24     ` jhc0033
  2008-05-17  7:50       ` Ivan Levashew
  0 siblings, 1 reply; 70+ messages in thread
From: jhc0033 @ 2008-05-17  5:24 UTC (permalink / raw)


On May 16, 3:59 pm, "Peter C. Chapin" <pcha...@sover.net> wrote:
> Maciej Sobczak wrote:
> > In Ada RAII is realized with controlled types.
>
> Controlled types in Ada are great, but I think C++ has a bit of an edge
> in this area (not considering the issue of the type hierarchy). In Ada,
> the compiler calls Adjust after it has finalized the object on the left
> side of an assignment. In C++ operator=() has access to both sides of
> the assignment at once.

In my opinion, the easiest and least error-prone approach to exception
safety in C++ is to design your code in such a way that you  can use
compiler-generated copy-constructors, assignment and destructors.

Incidentally, does Ada provide the programmer with automatic (and
overridabe) deep-copy assignment or copy-constructor?




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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
                   ` (2 preceding siblings ...)
  2008-05-16 22:45 ` anon
@ 2008-05-17  7:34 ` Pascal Obry
  2008-05-17 15:11   ` Bob Klungle
  2008-05-17 16:51   ` Maciej Sobczak
  2008-05-17 14:30 ` Brian Drummond
  2008-05-19  3:44 ` Matthew Heaney
  5 siblings, 2 replies; 70+ messages in thread
From: Pascal Obry @ 2008-05-17  7:34 UTC (permalink / raw)
  To: jhc0033@gmail.com

jhc0033@gmail.com a �crit :
> Did I misunderstand?

You have already received a bunch of excellent answers. I'd like to 
point out that in Ada you have less need for dynamically allocated 
memory. Ada supports unconstraint types. Objects of such types when 
declared can be "allocated" on the stack and passed around (no heap 
usage). A simple example:

    type Vector is (Positive range <>) of Float;

    function Norm (V : in Vector) return Float;

    ...

    declare
       V : Vector (1 .. 100);
       R : Float;
    begin
       R := Norm (V);
       ...

Not a single memory allocation. In C/C++ you'll need to dynamically 
allocate V on the heap, and then worry about freeing this memory.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17  5:24     ` jhc0033
@ 2008-05-17  7:50       ` Ivan Levashew
  0 siblings, 0 replies; 70+ messages in thread
From: Ivan Levashew @ 2008-05-17  7:50 UTC (permalink / raw)


jhc0033@gmail.com пишет:
> Incidentally, does Ada provide the programmer with automatic (and
> overridabe) deep-copy assignment or copy-constructor?

http://www.adaic.com/standards/05aarm/html/AA-7-6.html#I3652

-- 
If you want to get to the top, you have to start at the bottom



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
                   ` (3 preceding siblings ...)
  2008-05-17  7:34 ` Pascal Obry
@ 2008-05-17 14:30 ` Brian Drummond
  2008-05-17 16:47   ` Maciej Sobczak
  2008-05-18  8:06   ` Simon Wright
  2008-05-19  3:44 ` Matthew Heaney
  5 siblings, 2 replies; 70+ messages in thread
From: Brian Drummond @ 2008-05-17 14:30 UTC (permalink / raw)


On Fri, 16 May 2008 10:44:11 -0700 (PDT), "jhc0033@gmail.com"
<jhc0033@gmail.com> wrote:

>I'm mostly soliciting answers from Ada programmers who know C++ RAII
>well (Skip this if you use the words "C" and "C++" interchangeably,
>please. Your answers will be misleading at best):

Thank you for mentioning RAII. Not associating the acronym with the
concept, this prompted me to read about it, and from there to auto_ptr.

Which explained to me how changing from ptr to auto_ptr (presumably to
make code safer!) can introduce a spectacularly silly bug, completely
statically determinable, but which the compiler allows just fine and
lets the code die with a segfault.

One thing is clear to me: if you attempt to replicate C++ paradigms (as
opposed to OOP paradigms) in Ada, you will probably find Ada difficult.
But if you appreciate that about half the patterns in the "Gang of Four"
book only exist because of defects in C++, you will probably have an
easier time of it.

And no, I clearly do not consider myself a C++ programmer, but I
sometimes have to update something left behind by someone who did.

- Brian



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17  7:34 ` Pascal Obry
@ 2008-05-17 15:11   ` Bob Klungle
  2008-05-17 15:27     ` Pascal Obry
  2008-05-17 17:23     ` Martin Krischik
  2008-05-17 16:51   ` Maciej Sobczak
  1 sibling, 2 replies; 70+ messages in thread
From: Bob Klungle @ 2008-05-17 15:11 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1275 bytes --]


"Pascal Obry" <pascal@obry.net> wrote in message 
news:482E8A9D.5040401@obry.net...
> jhc0033@gmail.com a �crit :
>> Did I misunderstand?
>
> You have already received a bunch of excellent answers. I'd like to point 
> out that in Ada you have less need for dynamically allocated memory. Ada 
> supports unconstraint types. Objects of such types when declared can be 
> "allocated" on the stack and passed around (no heap usage). A simple 
> example:
>
>    type Vector is (Positive range <>) of Float;
>
>    function Norm (V : in Vector) return Float;
>
>    ...
>
>    declare
>       V : Vector (1 .. 100);
>       R : Float;
>    begin
>       R := Norm (V);
>       ...
>
> Not a single memory allocation. In C/C++ you'll need to dynamically 
> allocate V on the heap, and then worry about freeing this memory.
>
> Pascal.

Actually, the same construct exists in c/c++.
Stack frame allocation only needs a block to allow object definitions (c++ 
does it almost anywhere).
To whit:

#include <stdio.h>

int main(void)

{

    int x = 3;

    int y = 7;

    int z = 2;

    printf("x, y, z: %0d, %0d, %0d\n", x, y, z);

    {

        int w = 9;

        printf("x, y, z, w: %0d, %0d, %0d, %0d\n", x, y, z, w);

    }

}

x, y, z: 3, 7, 2

x, y, z, w: 3, 7, 2, 9





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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 15:11   ` Bob Klungle
@ 2008-05-17 15:27     ` Pascal Obry
  2008-05-17 16:18       ` Georg Bauhaus
  2008-05-20  8:01       ` Ole-Hjalmar Kristensen
  2008-05-17 17:23     ` Martin Krischik
  1 sibling, 2 replies; 70+ messages in thread
From: Pascal Obry @ 2008-05-17 15:27 UTC (permalink / raw)
  To: Bob Klungle

Bob Klungle a �crit :
> "Pascal Obry" <pascal@obry.net> wrote in message 
> news:482E8A9D.5040401@obry.net...
>> jhc0033@gmail.com a �crit :
>>> Did I misunderstand?
>> You have already received a bunch of excellent answers. I'd like to point 
>> out that in Ada you have less need for dynamically allocated memory. Ada 
>> supports unconstraint types. Objects of such types when declared can be 
>> "allocated" on the stack and passed around (no heap usage). A simple 
>> example:
>>
>>    type Vector is (Positive range <>) of Float;
>>
>>    function Norm (V : in Vector) return Float;
>>
>>    ...
>>
>>    declare
>>       V : Vector (1 .. 100);
>>       R : Float;
>>    begin
>>       R := Norm (V);
>>       ...
>>
>> Not a single memory allocation. In C/C++ you'll need to dynamically 
>> allocate V on the heap, and then worry about freeing this memory.
>>
>> Pascal.
> 
> Actually, the same construct exists in c/c++.

Ok, I meant a non statically known constraint. My example was not 
accurate enough then.

    type Vector is (Positive range <>) of Float;

    function Norm (V : in Vector) return Float;

    ...

    N := <runtime computed value>;

    declare
       V : Vector (1 .. N);
       R : Float;
    begin
       R := Norm (V);
       ...

> Stack frame allocation only needs a block to allow object definitions (c++ 
> does it almost anywhere).

And for anything else when the size of the object is not known at 
compile time. That's why I talked specifically about unconstraint objects.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 15:27     ` Pascal Obry
@ 2008-05-17 16:18       ` Georg Bauhaus
  2008-05-20  8:04         ` Ole-Hjalmar Kristensen
  2008-05-20  8:01       ` Ole-Hjalmar Kristensen
  1 sibling, 1 reply; 70+ messages in thread
From: Georg Bauhaus @ 2008-05-17 16:18 UTC (permalink / raw)


Pascal Obry wrote:
> Bob Klungle a �crit :

>> Actually, the same construct exists in c/c++.
> 
> Ok, I meant a non statically known constraint. My example was not
> accurate enough then.
> 
>    type Vector is (Positive range <>) of Float;
> 
>    function Norm (V : in Vector) return Float;
> 
>    ...
> 
>    N := <runtime computed value>;
> 
>    declare
>       V : Vector (1 .. N);
>       R : Float;
>    begin
>       R := Norm (V);
>       ...


This won't convince a C++ programmer because they have typed
template Lisp, checked element access, container properties,
and stack allocated aggregates.

What C++ does not have is full nesting, including access to
auto variables of surrounding scopes and to function parameters.
(This can be of use as demonstrated by Integrate and Iterate.)
You can have local classes in C++ and even mimic local subprograms
but this is clumsy.

Ada nesting entails very straight forward lifetime control,
much underused IMHO. (Plus GNAT performance is not as good as
when everything is at library level.) Using scopes, you can
control static and dynamic lifetimes types and objects
(including tasks!).
But somehow I think people are obsessed with making each and
every type fully general and usable at library level (and in
theory books and papers?), simply dismissing possibilities that
declarative regions offer naturally. Is this a consequence of
teaching and hyping mostly flat languages?




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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 14:30 ` Brian Drummond
@ 2008-05-17 16:47   ` Maciej Sobczak
  2008-05-19 14:45     ` Brian Drummond
  2008-05-18  8:06   ` Simon Wright
  1 sibling, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-17 16:47 UTC (permalink / raw)


On 17 Maj, 16:30, Brian Drummond <brian_drumm...@btconnect.com> wrote:

> But if you appreciate that about half the patterns in the "Gang of Four"
> book only exist because of defects in C++

Please name those patterns.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17  7:34 ` Pascal Obry
  2008-05-17 15:11   ` Bob Klungle
@ 2008-05-17 16:51   ` Maciej Sobczak
  2008-05-17 17:45     ` Pascal Obry
  2008-05-18  6:52     ` Martin Krischik
  1 sibling, 2 replies; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-17 16:51 UTC (permalink / raw)


On 17 Maj, 09:34, Pascal Obry <pas...@obry.net> wrote:

>     function Norm (V : in Vector) return Float;
>
>     ...
>
>     declare
>        V : Vector (1 .. 100);
>        R : Float;
>     begin
>        R := Norm (V);
>        ...
>
> Not a single memory allocation. In C/C++ you'll need to dynamically
> allocate V on the heap, and then worry about freeing this memory.

Sorry for being a bit rude, but OP explicitly said that this is not
for those who use the names C and C++ interchangeably. :-)
The C++ programmer would do this:

float norm(const vector<float> & v);

// and then:
vector<float> v(100);
// ...
float r = norm(v);

No explicit allocation on the heap and no worry about deallocation. It
is all automatic.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 15:11   ` Bob Klungle
  2008-05-17 15:27     ` Pascal Obry
@ 2008-05-17 17:23     ` Martin Krischik
  1 sibling, 0 replies; 70+ messages in thread
From: Martin Krischik @ 2008-05-17 17:23 UTC (permalink / raw)


Bob Klungle wrote:

> Actually, the same construct exists in c/c++.
> Stack frame allocation only needs a block to allow object definitions (c++
> does it almost anywhere).
> To whit:
> 
> #include <stdio.h>
> 
> int main(void)
> 
> {
>     int x = 3;
>     int y = 7;

To make is more complicated make that:

     int y = f (x);

>     int z = 2;
>     printf("x, y, z: %0d, %0d, %0d\n", x, y, z);
>     {
>         int w = 9;

And here in Ada you can have:

           int v [y];

Note that C99 supports this construct as well, however there is only one
compiler that implements this particular feature.

And yes I know about vector<> - in fact Ada has a generic Vector class as
well.
 
>         printf("x, y, z, w: %0d, %0d, %0d, %0d\n", x, y, z, w);
> 
>     }
> 
> }

Martin

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 16:51   ` Maciej Sobczak
@ 2008-05-17 17:45     ` Pascal Obry
  2008-05-17 22:28       ` Samuel Tardieu
  2008-05-17 22:42       ` Peter C. Chapin
  2008-05-18  6:52     ` Martin Krischik
  1 sibling, 2 replies; 70+ messages in thread
From: Pascal Obry @ 2008-05-17 17:45 UTC (permalink / raw)
  To: Maciej Sobczak

Maciej,

> Sorry for being a bit rude, but OP explicitly said that this is not
> for those who use the names C and C++ interchangeably. :-)

Sorry for being a bit rude but...

> float norm(const vector<float> & v);
> 
> // and then:
> vector<float> v(100);

is simpler written as:

    float v[100];

and the point was about a constraint not known at compile time.

AFAIK

     int N;

     N = <value computed at runtime>;

     vector<float> v(N);

Is not C++. And this was only a simple example for the OP. I'm talking 
about all objects whose constraint are not known at compile time.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 17:45     ` Pascal Obry
@ 2008-05-17 22:28       ` Samuel Tardieu
  2008-05-18  7:03         ` Martin Krischik
  2008-05-17 22:42       ` Peter C. Chapin
  1 sibling, 1 reply; 70+ messages in thread
From: Samuel Tardieu @ 2008-05-17 22:28 UTC (permalink / raw)


>>>>> "Pascal" == Pascal Obry <pascal@obry.net> writes:

Pascal> AFAIK
Pascal>     int N;
Pascal>     N = <value computed at runtime>;
Pascal>     vector<float> v(N);
Pascal> Is not C++.

What do you mean? This is perfectly legal in C++.

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 17:45     ` Pascal Obry
  2008-05-17 22:28       ` Samuel Tardieu
@ 2008-05-17 22:42       ` Peter C. Chapin
  2008-05-18  6:58         ` Martin Krischik
  1 sibling, 1 reply; 70+ messages in thread
From: Peter C. Chapin @ 2008-05-17 22:42 UTC (permalink / raw)


Pascal Obry wrote:

>     int N;
> 
>     N = <value computed at runtime>;
> 
>     vector<float> v(N);

This is legal in C++. The constructor parameter is an arbitrary expression.

This discussion is starting to compare language+library vs language. 
There be dragons down that road!

Peter



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 16:51   ` Maciej Sobczak
  2008-05-17 17:45     ` Pascal Obry
@ 2008-05-18  6:52     ` Martin Krischik
  2008-05-18 14:16       ` Maciej Sobczak
  1 sibling, 1 reply; 70+ messages in thread
From: Martin Krischik @ 2008-05-18  6:52 UTC (permalink / raw)


Maciej Sobczak wrote:

> // and then:
> vector<float> v(100);

In which case we don't compare languages anymore but libraries and then you
can write a vector library in any language including assembler.

Martin

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 22:42       ` Peter C. Chapin
@ 2008-05-18  6:58         ` Martin Krischik
  0 siblings, 0 replies; 70+ messages in thread
From: Martin Krischik @ 2008-05-18  6:58 UTC (permalink / raw)


Peter C. Chapin wrote:

> Pascal Obry wrote:
> 
>>     int N;
>> 
>>     N = <value computed at runtime>;
>> 
>>     vector<float> v(N);
> 
> This is legal in C++. The constructor parameter is an arbitrary
> expression.
> 
> This discussion is starting to compare language+library vs language.

Both C++ and Java advocates like that kind of comparison as both are rather
weak languages with powerfull libraries.

Mind you some of the Java programmers I work with start to become
dissatisfied with the weakness of Java and start to look for alternatives
targeting the JVM and it's huge library.

> There be dragons down that road!

Indeed.

Martin

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 22:28       ` Samuel Tardieu
@ 2008-05-18  7:03         ` Martin Krischik
  2008-05-18  8:50           ` jhc0033
  0 siblings, 1 reply; 70+ messages in thread
From: Martin Krischik @ 2008-05-18  7:03 UTC (permalink / raw)


Samuel Tardieu wrote:

>>>>>> "Pascal" == Pascal Obry <pascal@obry.net> writes:
> 
> Pascal> AFAIK
> Pascal>     int N;
> Pascal>     N = <value computed at runtime>;
> Pascal>     vector<float> v(N);
> Pascal> Is not C++.
> 
> What do you mean? This is perfectly legal in C++.

#include <vector> is missing for it to become "perfectly legal". This is the
typical cheat of C++ advocates - selling there standart library as
languages features.

But that is unfair as vector<> can be implemented in any language including
assember.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 14:30 ` Brian Drummond
  2008-05-17 16:47   ` Maciej Sobczak
@ 2008-05-18  8:06   ` Simon Wright
  2008-05-18 14:21     ` Maciej Sobczak
  2008-05-19 14:40     ` Brian Drummond
  1 sibling, 2 replies; 70+ messages in thread
From: Simon Wright @ 2008-05-18  8:06 UTC (permalink / raw)


Brian Drummond <brian_drummond@btconnect.com> writes:

> Which explained to me how changing from ptr to auto_ptr (presumably
> to make code safer!) can introduce a spectacularly silly bug,
> completely statically determinable, but which the compiler allows
> just fine and lets the code die with a segfault.

Is auto_ptr the one where assignment moves the content? "b = a;" means
that a is now null and b references the previous content of a?

If so, it seems to me that it's the concept that's spectacularly
silly! (I considered introducing an auto pointer into the Booch
Components, but then thought about using it .. I can see that there
might be a use within a very narrow scope, but a standard ref-counted
smart pointer works just as well. No doubt there is an appropriate
usage idiom?)



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  7:03         ` Martin Krischik
@ 2008-05-18  8:50           ` jhc0033
  2008-05-18  9:31             ` Dmitry A. Kazakov
  2008-05-18 15:03             ` Martin Krischik
  0 siblings, 2 replies; 70+ messages in thread
From: jhc0033 @ 2008-05-18  8:50 UTC (permalink / raw)


On May 18, 12:03 am, Martin Krischik <krisc...@users.sourceforge.net>
wrote:
> Samuel Tardieu wrote:
> >>>>>> "Pascal" == Pascal Obry <pas...@obry.net> writes:
>
> > Pascal> AFAIK
> > Pascal>     int N;
> > Pascal>     N = <value computed at runtime>;
> > Pascal>     vector<float> v(N);
> > Pascal> Is not C++.
>
> > What do you mean? This is perfectly legal in C++.
>
> #include <vector> is missing for it to become "perfectly legal". This is the
> typical cheat of C++ advocates - selling there standart library as
> languages features.

So if the C++ standard said: "<vector> is included by default", that
would make C++ a better language in your opinion?

> But that is unfair as vector<> can be implemented in any language including
> assember.

Oh, panlinguistic guru, I'd like to see you try to implement "STL" in
C! I wonder if you'll go for macros or void* type casts with type
sizes as explicit parameters. How will you implement automatic memory
management and deep copy semantics for arbitrary user-constructed type
parameters?



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  8:50           ` jhc0033
@ 2008-05-18  9:31             ` Dmitry A. Kazakov
  2008-05-18 14:10               ` Maciej Sobczak
  2008-05-18 15:03             ` Martin Krischik
  1 sibling, 1 reply; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-18  9:31 UTC (permalink / raw)


On Sun, 18 May 2008 01:50:21 -0700 (PDT), jhc0033@gmail.com wrote:

> On May 18, 12:03 am, Martin Krischik <krisc...@users.sourceforge.net>
> wrote:

>> #include <vector> is missing for it to become "perfectly legal". This is the
>> typical cheat of C++ advocates - selling there standart library as
>> languages features.
> 
> So if the C++ standard said: "<vector> is included by default", that
> would make C++ a better language in your opinion?

Right, actually less built-in types a language has, the better the language
is.

The problem with C++ and vector is not that vector is not built-in. It is
that vector cannot have a treatment fully equal to a built-in type:

1. Its body cannot be allocated on the stack.
2. It is not a proper type (requires parametrization)
3. Optimization. I have doubts that small vectors could be passed by value,
loops over them unrolled, values cached in registers, that static bounds
checking could be enforced at compile time and skipped at run-time etc.

Further, the array abstraction is incomplete:

4. It does not have a class over the element type
5. It does not have a class over the index type

(Ada does not have 4-5 either)

>> But that is unfair as vector<> can be implemented in any language including
>> assember.
> 
> Oh, panlinguistic guru, I'd like to see you try to implement "STL" in
> C! I wonder if you'll go for macros or void* type casts with type
> sizes as explicit parameters. How will you implement automatic memory
> management and deep copy semantics for arbitrary user-constructed type
> parameters?

This is a misunderstanding. Clearly, it is doable in any Turing-complete
language. The problem is how much an implementation could be disguised as a
normal array type. However, because assembler does not have much types
anyway, where is a problem? (:-))

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  9:31             ` Dmitry A. Kazakov
@ 2008-05-18 14:10               ` Maciej Sobczak
  2008-05-18 14:59                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-18 14:10 UTC (permalink / raw)


On 18 Maj, 11:31, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> The problem with C++ and vector is not that vector is not built-in. It is
> that vector cannot have a treatment fully equal to a built-in type:
>
> 1. Its body cannot be allocated on the stack.

What is "body"?
The vector can be allocated on the stack and be formally an object
with automatic storage duration (there is no "stack" in C++, BTW). It
can have some of its state elsewhere, but this is not your concern -
the buzzword for this is "encapsulation".

Note also that there exists what is called a "short vector
optimization" (SVO), more often used for strings.

> 2. It is not a proper type (requires parametrization)

Is it wrong?

> 3. Optimization. I have doubts that small vectors could be passed by value,
> loops over them unrolled, values cached in registers, that static bounds
> checking could be enforced at compile time and skipped at run-time etc.

All of these can be done.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  6:52     ` Martin Krischik
@ 2008-05-18 14:16       ` Maciej Sobczak
  0 siblings, 0 replies; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-18 14:16 UTC (permalink / raw)


On 18 Maj, 08:52, Martin Krischik <krisc...@users.sourceforge.net>
wrote:
> Maciej Sobczak wrote:
> > // and then:
> > vector<float> v(100);
>
> In which case we don't compare languages anymore but libraries

Both are defined by the same standard document. I don't see why we
should distinguish them - from practical perspective there is no
distinction at all. Note also that language and its standard library
usually have a rather fuzzy border, even in system-oriented languages
like Ada and C++. In other words, it is difficult to separate the two.

For example: is Root_Stream_Type a language or a library feature
(hint: S'Write/Read/etc.)?

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  8:06   ` Simon Wright
@ 2008-05-18 14:21     ` Maciej Sobczak
  2008-05-18 20:48       ` Simon Wright
  2008-05-19 14:40     ` Brian Drummond
  1 sibling, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-18 14:21 UTC (permalink / raw)


On 18 Maj, 10:06, Simon Wright <simon.j.wri...@mac.com> wrote:

> Is auto_ptr the one where assignment moves the content? "b = a;" means
> that a is now null and b references the previous content of a?

Yes.

> If so, it seems to me that it's the concept that's spectacularly
> silly!

It has its own very reasonable use case: safe returning dynamically
allocated objects from functions.

Outside of this single use case, you'd rather use scoped_ptr (maybe as
unique_ptr) or shared_ptr.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 14:10               ` Maciej Sobczak
@ 2008-05-18 14:59                 ` Dmitry A. Kazakov
  2008-05-18 20:51                   ` Maciej Sobczak
  0 siblings, 1 reply; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-18 14:59 UTC (permalink / raw)


On Sun, 18 May 2008 07:10:55 -0700 (PDT), Maciej Sobczak wrote:

> On 18 Maj, 11:31, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>> The problem with C++ and vector is not that vector is not built-in. It is
>> that vector cannot have a treatment fully equal to a built-in type:
>>
>> 1. Its body cannot be allocated on the stack.
> 
> What is "body"?

Storage used to keep the array elements.

>> 2. It is not a proper type (requires parametrization)
> 
> Is it wrong?

Yes. It has no values and no operations.

>> 3. Optimization. I have doubts that small vectors could be passed by value,
>> loops over them unrolled, values cached in registers, that static bounds
>> checking could be enforced at compile time and skipped at run-time etc.
> 
> All of these can be done.

Is there a C++ compiler that does this?

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  8:50           ` jhc0033
  2008-05-18  9:31             ` Dmitry A. Kazakov
@ 2008-05-18 15:03             ` Martin Krischik
  2008-05-18 18:27               ` jhc0033
  1 sibling, 1 reply; 70+ messages in thread
From: Martin Krischik @ 2008-05-18 15:03 UTC (permalink / raw)


jhc0033@gmail.com wrote:

> Oh, panlinguistic guru, I'd like to see you try to implement "STL" in
> C! I wonder if you'll go for macros or void* type casts with type
> sizes as explicit parameters. How will you implement automatic memory
> management and deep copy semantics for arbitrary user-constructed type
> parameters?

I start with:

typeset struct Vector Vector;

Vector* Create_Vector(int Element_Count, size_t Element_Size);

and take it from there. Won't have the same syntax - but the semantic is
doable.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 15:03             ` Martin Krischik
@ 2008-05-18 18:27               ` jhc0033
  2008-05-19  4:12                 ` Matthew Heaney
  2008-05-19 10:27                 ` Martin Krischik
  0 siblings, 2 replies; 70+ messages in thread
From: jhc0033 @ 2008-05-18 18:27 UTC (permalink / raw)


On May 18, 8:03 am, Martin Krischik <krisc...@users.sourceforge.net>
wrote:
> jhc0...@gmail.com wrote:
> > Oh, panlinguistic guru, I'd like to see you try to implement "STL" in
> > C! I wonder if you'll go for macros or void* type casts with type
> > sizes as explicit parameters. How will you implement automatic memory
> > management and deep copy semantics for arbitrary user-constructed type
> > parameters?
>
> I start with:
>
> typeset struct Vector Vector;
>
> Vector* Create_Vector(int Element_Count, size_t Element_Size);

Already, this can not do what "vector<my_type> v(n)" does.

> and take it from there. Won't have the same syntax - but the semantic is
> doable.

That's because you don't understand what RAII is, or how it interacts
with "return" and exceptions.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 14:21     ` Maciej Sobczak
@ 2008-05-18 20:48       ` Simon Wright
  0 siblings, 0 replies; 70+ messages in thread
From: Simon Wright @ 2008-05-18 20:48 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> On 18 Maj, 10:06, Simon Wright <simon.j.wri...@mac.com> wrote:
>
>> Is auto_ptr the one where assignment moves the content? "b = a;"
>> means that a is now null and b references the previous content of
>> a?
>
> Yes.
>
>> If so, it seems to me that it's the concept that's spectacularly
>> silly!
>
> It has its own very reasonable use case: safe returning dynamically
> allocated objects from functions.

That was the use I'd thought of.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 14:59                 ` Dmitry A. Kazakov
@ 2008-05-18 20:51                   ` Maciej Sobczak
  2008-05-19  8:36                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-18 20:51 UTC (permalink / raw)


On 18 Maj, 16:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> >> 1. Its body cannot be allocated on the stack.
>
> > What is "body"?
>
> Storage used to keep the array elements.

From when should we care where it is?

> >> 2. It is not a proper type (requires parametrization)
>
> > Is it wrong?
>
> Yes. It has no values and no operations.

Can I say that arrays in Ada also have no values and no operations
until they are parapeterized with element and index type (and
constrained)?

> >> 3. Optimization. I have doubts that small vectors could be passed by value,
> >> loops over them unrolled, values cached in registers, that static bounds
> >> checking could be enforced at compile time and skipped at run-time etc.
>
> > All of these can be done.
>
> Is there a C++ compiler that does this?

You had doubts whether it *could* be done, not whether it *is*
done. :-) There is nothing fundamental that would prevent it.
Note that vector is a *standard* feature - so the compiler knows what
it does and how.

In any case, check the Intel C++ compiler. It is known for some nice
optimization tricks.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
                   ` (4 preceding siblings ...)
  2008-05-17 14:30 ` Brian Drummond
@ 2008-05-19  3:44 ` Matthew Heaney
  5 siblings, 0 replies; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19  3:44 UTC (permalink / raw)


On May 16, 1:44 pm, "jhc0...@gmail.com" <jhc0...@gmail.com> wrote:
>
> To me, this seems much, much more error-prone and tedious that C++'s
> RAII approach, where you almost never have to worry about deallocation
> (i.e. "b" and "c" above), even in the presence of exceptions, unless
> you have GC. Besides, RAII applies to a bunch of other things, like
> thread locks, database connections, files - not just memory.

You seem to be conflating two different things.  You want information
about RAII in Ada, but then ask about memory management in Ada.
Stroustrup's whole point that GC only solves one part (automation
memory reclaimation) of a larger problem (automation resource
reclaimation).  You yourself do mention this fact, but only in the
very last sentence of your post!

Yes, Ada has the analog of C++ ctor's and dtor's, so yes, you can do
RAII in Ada.  Usually it involves the use of
Ada.Finalization.Controlled (and really, just the Finalize part).




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

* Re: memory management in Ada: tedious without GC?
  2008-05-16 20:42 ` Maciej Sobczak
                     ` (2 preceding siblings ...)
  2008-05-16 23:05   ` Randy Brukardt
@ 2008-05-19  3:50   ` Matthew Heaney
  2008-05-19  7:55     ` Dmitry A. Kazakov
  2008-05-19  8:35     ` Maciej Sobczak
  3 siblings, 2 replies; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19  3:50 UTC (permalink / raw)


On May 16, 4:42 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> In Ada RAII is realized with controlled types. They are severely
> broken in that they are intrusive in the type hierarchy and they burn
> the whole budget for implementation inheritance,

No, this is wrong.  You can add in Controlled-ness as far down the
hierarchy as you like, by adding a controlled component.

Furthermore, if you blow your budget in Ada, then you blow in C++ too,
since invoking Finalization in Ada is the same as invoking a dtor in C+
+.




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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 18:27               ` jhc0033
@ 2008-05-19  4:12                 ` Matthew Heaney
  2008-05-19  8:39                   ` Maciej Sobczak
  2008-05-19 10:27                 ` Martin Krischik
  1 sibling, 1 reply; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19  4:12 UTC (permalink / raw)


On May 18, 2:27 pm, "jhc0...@gmail.com" <jhc0...@gmail.com> wrote:
> That's because you don't understand what RAII is, or how it interacts
> with "return" and exceptions.

Right, and Ada gives you the tools to right exception-safe
abstractions, that don't leak memory (or any other resource).  It's
really no different from C++.





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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  3:50   ` Matthew Heaney
@ 2008-05-19  7:55     ` Dmitry A. Kazakov
  2008-05-19 13:18       ` Georg Bauhaus
  2008-05-23 23:15       ` Robert A Duff
  2008-05-19  8:35     ` Maciej Sobczak
  1 sibling, 2 replies; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-19  7:55 UTC (permalink / raw)


On Sun, 18 May 2008 20:50:48 -0700 (PDT), Matthew Heaney wrote:

> On May 16, 4:42�pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>
>> In Ada RAII is realized with controlled types. They are severely
>> broken in that they are intrusive in the type hierarchy and they burn
>> the whole budget for implementation inheritance,
> 
> No, this is wrong.  You can add in Controlled-ness as far down the
> hierarchy as you like, by adding a controlled component.

This is broken too:

1. You don't know exactly the order in which the Finalize of the controlled
component gets called.  So if you access the container object over an
access discriminant, that might be already invalid.

2. Similarly, Initialize might be called before the container object is
fully operational.

3. Access discriminant would require controlled object to become limited,
so must be the container.

4. The pattern is exposed to multiple inheritance diamond diagram problem,
when such components are added independently.

> Furthermore, if you blow your budget in Ada, then you blow in C++ too,
> since invoking Finalization in Ada is the same as invoking a dtor in C+

Well, I suggest that the overhead required in C++ for maintenance virtual
destructors should be lower than one Ada.Finalization. For example it does
not require linked list of objects.

IMO, initialization/finalization hooks shall be definable for all types.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  3:50   ` Matthew Heaney
  2008-05-19  7:55     ` Dmitry A. Kazakov
@ 2008-05-19  8:35     ` Maciej Sobczak
  2008-05-19 15:11       ` Matthew Heaney
  1 sibling, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-19  8:35 UTC (permalink / raw)


On 19 Maj, 05:50, Matthew Heaney <mhea...@on2.com> wrote:

> > In Ada RAII is realized with controlled types. They are severely
> > broken in that they are intrusive in the type hierarchy and they burn
> > the whole budget for implementation inheritance,
>
> No, this is wrong.  You can add in Controlled-ness as far down the
> hierarchy as you like, by adding a controlled component.

Good to know.
(But it is also good to know what Dmitry replied.)

How would you use this strategy to make a controlled stream (derived
from Root_Stream_Type)?

> Furthermore, if you blow your budget in Ada, then you blow in C++ too,

No. Adding a destructor in C++ does not blow any budget - it is
independent of the hierarchy (and the hierarchy supports multiple
inheritance anyway, so the budget is not constrained even if it would
be used).

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 20:51                   ` Maciej Sobczak
@ 2008-05-19  8:36                     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-19  8:36 UTC (permalink / raw)


On Sun, 18 May 2008 13:51:44 -0700 (PDT), Maciej Sobczak wrote:

> On 18 Maj, 16:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>>>> 1. Its body cannot be allocated on the stack.
>>
>>> What is "body"?
>>
>> Storage used to keep the array elements.
> 
> From when should we care where it is?

We don't want to care, it means to have the least strict requirements on
the storage. It should be possible to allocate it in the task local
storage, or in the storage having certain allocation policy. One
implementation constraint which satisfies these requirements is that the
object is contiguous. Maybe, one could relax it, but I don't see a good way
to it.

>>>> 2. It is not a proper type (requires parametrization)
>>
>>> Is it wrong?
>>
>> Yes. It has no values and no operations.
> 
> Can I say that arrays in Ada also have no values and no operations
> until they are parapeterized with element and index type (and
> constrained)?

Right, these are points 4-5 of my earlier post.

>>>> 3. Optimization. I have doubts that small vectors could be passed by value,
>>>> loops over them unrolled, values cached in registers, that static bounds
>>>> checking could be enforced at compile time and skipped at run-time etc.
>>
>>> All of these can be done.
>>
>> Is there a C++ compiler that does this?
> 
> You had doubts whether it *could* be done, not whether it *is*
> done. :-) There is nothing fundamental that would prevent it.
> Note that vector is a *standard* feature - so the compiler knows what
> it does and how.

Ah, that is the point. The compiler shall know if something is an array. In
Ada, which "has arrays" the language tells the compiler - here is one. In
C++, which "does not have arrays", it is the name of the template that
should convey the idea. What happens if I modify or rename the template?

This is an argument for having, not arrays, but their interfaces built-in
in the language. Both Ada and C++ are wrong here. I don't understand why
C++ advocates feel offended when somebody tells that C++ does not have
arrays. They should be proud of this. C++ has better means for array
interfaces than Ada has. These are not templates or vector<>, but
operator[].

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  4:12                 ` Matthew Heaney
@ 2008-05-19  8:39                   ` Maciej Sobczak
  2008-05-19 15:37                     ` Matthew Heaney
  0 siblings, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-19  8:39 UTC (permalink / raw)


On 19 Maj, 06:12, Matthew Heaney <mhea...@on2.com> wrote:

> Right, and Ada gives you the tools to right exception-safe
> abstractions, that don't leak memory (or any other resource).  It's
> really no different from C++.

I've found two differences:
1. No support for exception-safe assignment in Ada.
2. Memory leak after exception is raised while initializing the
allocated object in Ada.

Apart from these two I find Ada and C++ approaches very similar (and
appropriate).

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18 18:27               ` jhc0033
  2008-05-19  4:12                 ` Matthew Heaney
@ 2008-05-19 10:27                 ` Martin Krischik
  1 sibling, 0 replies; 70+ messages in thread
From: Martin Krischik @ 2008-05-19 10:27 UTC (permalink / raw)


jhc0033@gmail.com schrieb:
> On May 18, 8:03 am, Martin Krischik <krisc...@users.sourceforge.net>
> wrote:
>> jhc0...@gmail.com wrote:
>>> Oh, panlinguistic guru, I'd like to see you try to implement "STL" in
>>> C! I wonder if you'll go for macros or void* type casts with type
>>> sizes as explicit parameters. How will you implement automatic memory
>>> management and deep copy semantics for arbitrary user-constructed type
>>> parameters?
>> I start with:
>>
>> typeset struct Vector Vector;
>>
>> Vector* Create_Vector(int Element_Count, size_t Element_Size);
> 
> Already, this can not do what "vector<my_type> v(n)" does.
> 
>> and take it from there. Won't have the same syntax - but the semantic is
>> doable.
> 
> That's because you don't understand what RAII is, or how it interacts
> with "return" and exceptions.


I see, you insist that:

typedef Element* Element_Create();
typedef Element_Destroy(Element* An_Element);

is passed as parameters to Create_Vector so Vector can initialize and 
terminate Elements.

Ok, the syntax gets ugly, and there is some nasty casting needed now but 
still doable.

Note that while I think it was a mistake to do so GNOME is a OO 
Framework based on C.

Regards

Martin

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  7:55     ` Dmitry A. Kazakov
@ 2008-05-19 13:18       ` Georg Bauhaus
  2008-05-19 14:16         ` Dmitry A. Kazakov
  2008-05-23 23:15       ` Robert A Duff
  1 sibling, 1 reply; 70+ messages in thread
From: Georg Bauhaus @ 2008-05-19 13:18 UTC (permalink / raw)


Dmitry A. Kazakov schrieb:
> On Sun, 18 May 2008 20:50:48 -0700 (PDT), Matthew Heaney wrote:
> 
>> On May 16, 4:42 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>> In Ada RAII is realized with controlled types. They are severely
>>> broken in that they are intrusive in the type hierarchy and they burn
>>> the whole budget for implementation inheritance,
>> No, this is wrong.  You can add in Controlled-ness as far down the
>> hierarchy as you like, by adding a controlled component.
> 
> This is broken too:
> 
> 1. You don't know exactly the order in which the Finalize of the controlled
> component gets called.  So if you access the container object over an
> access discriminant, that might be already invalid.

When you design a type T, should the aspects of "death"
of an object affect the "live" aspects of T objects at all?
Death happens at a defined moment. What happens at this
moment is conceptually separate from what happens while
the object is alive, even though there are relations
between births, lives, and deaths, of course.

But why lump together these two aspects of dynamics in the
same type?
Why not have types, task types perhaps, that take care
of the post mortem affairs of related types? (Other than
wasting the bits maybe.)

We have Factories. Why not have Incineration_Plants or
similar, with well defined protocols?
I certainly find it strange having to think of the
topological orderings of cleanup work when I focus on
what objects of a type should actually do (to do ==>
still alive).



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 13:18       ` Georg Bauhaus
@ 2008-05-19 14:16         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-19 14:16 UTC (permalink / raw)


On Mon, 19 May 2008 15:18:48 +0200, Georg Bauhaus wrote:

> Dmitry A. Kazakov schrieb:
>> On Sun, 18 May 2008 20:50:48 -0700 (PDT), Matthew Heaney wrote:
>> 
>>> On May 16, 4:42 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>>> In Ada RAII is realized with controlled types. They are severely
>>>> broken in that they are intrusive in the type hierarchy and they burn
>>>> the whole budget for implementation inheritance,
>>> No, this is wrong.  You can add in Controlled-ness as far down the
>>> hierarchy as you like, by adding a controlled component.
>> 
>> This is broken too:
>> 
>> 1. You don't know exactly the order in which the Finalize of the controlled
>> component gets called.  So if you access the container object over an
>> access discriminant, that might be already invalid.
> 
> When you design a type T, should the aspects of "death"
> of an object affect the "live" aspects of T objects at all?
> Death happens at a defined moment. What happens at this
> moment is conceptually separate from what happens while
> the object is alive, even though there are relations
> between births, lives, and deaths, of course.

When an object is constructed by a public or private composition of other
objects, that breaks this separation. The life span of a component is
longer than of the record it contains. (Exactly same problem arise upon
inheritance.) Thus a component exists before the official birth and after
the death of the whole. The problem is no different from dispatching upon
construction/destruction.

The only solution is to split construction/destruction into multiple
stages, introducing class-wide constructors/destructors. Class here is
"Root_Record_Component_Type'Class."  So when, say, T is put into a record
R, then T inherits from Root_Record_Component_Type and can attach some hook
onto the constructor of the class. That constructor is a part of the
constructor of R'Class. This code will be called after construction of all
components of R and also after construction of R.

In short, T constructed as itself and T constructed as a component of
something else are not equivalent. The latter is more than the former.

> But why lump together these two aspects of dynamics in the
> same type?

Because these are two aspects of the same thing.

> Why not have types, task types perhaps, that take care
> of the post mortem affairs of related types? (Other than
> wasting the bits maybe.)

Why switching context before running a constructor should change anything?
The contradiction to the life span exists independently on that.

> We have Factories. Why not have Incineration_Plants or
> similar, with well defined protocols?
> I certainly find it strange having to think of the
> topological orderings of cleanup work when I focus on
> what objects of a type should actually do (to do ==>
> still alive).

Because these are issues are of the types algebra you have to use in order
to construct the type of the object. If you want that algebra, i.e.
records, arrays, access types construction primitives, then you have to
face the problem.

Object doing things is miles beneath that abstraction level. It's not even
typed. Types operate sets of objects. Algebra of types operates sets of
types.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-18  8:06   ` Simon Wright
  2008-05-18 14:21     ` Maciej Sobczak
@ 2008-05-19 14:40     ` Brian Drummond
  1 sibling, 0 replies; 70+ messages in thread
From: Brian Drummond @ 2008-05-19 14:40 UTC (permalink / raw)


On Sun, 18 May 2008 09:06:55 +0100, Simon Wright
<simon.j.wright@mac.com> wrote:

>Brian Drummond <brian_drummond@btconnect.com> writes:
>
>> Which explained to me how changing from ptr to auto_ptr (presumably
>> to make code safer!) can introduce a spectacularly silly bug,
>> completely statically determinable, but which the compiler allows
>> just fine and lets the code die with a segfault.
>
>Is auto_ptr the one where assignment moves the content? "b = a;" means
>that a is now null and b references the previous content of a?
>
>If so, it seems to me that it's the concept that's spectacularly
>silly! (I considered introducing an auto pointer into the Booch
>Components, but then thought about using it .. I can see that there
>might be a use within a very narrow scope, but a standard ref-counted
>smart pointer works just as well. No doubt there is an appropriate
>usage idiom?)

That's the one. It's maybe not spectacularly silly; I can see how it
would help in other circumstances, but not here. 

Maciek is probably right that one or more of scoped_ptr, unique_ptr or
shared_ptr would be a better choice, but that is where I want to part
company with C++[+STL] - that looks like four new mechanisms to increase
complexity, without eliminating the basic problems of ptr.

I would prefer to catch problems at (or even before) the compiler,
rather than as here, let them manifest at runtime. So, having assigned
b=a, at the very least, any further references to 'a' in the same block
ought to be grounds for compilation failure. But apparently not, at
least in this compiler (gcc).

- Brian



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 16:47   ` Maciej Sobczak
@ 2008-05-19 14:45     ` Brian Drummond
  2008-05-20  7:42       ` Maciej Sobczak
  0 siblings, 1 reply; 70+ messages in thread
From: Brian Drummond @ 2008-05-19 14:45 UTC (permalink / raw)


On Sat, 17 May 2008 09:47:37 -0700 (PDT), Maciej Sobczak
<see.my.homepage@gmail.com> wrote:

>On 17 Maj, 16:30, Brian Drummond <brian_drumm...@btconnect.com> wrote:
>
>> But if you appreciate that about half the patterns in the "Gang of Four"
>> book only exist because of defects in C++
>
>Please name those patterns.

I must apologise, I'm going to have to wimp out of providing them, at
least until I can re-read the book properly. 

But a sketch answer; a lot of them seemed to be about how to discipline
oneself to achieve various aspects of information hiding or separation
between interface and implementation, that a better type system would
have achieved automatically, or nearly so.

- Brian



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  8:35     ` Maciej Sobczak
@ 2008-05-19 15:11       ` Matthew Heaney
  2008-05-19 21:13         ` Maciej Sobczak
  2008-05-23 23:03         ` Robert A Duff
  0 siblings, 2 replies; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19 15:11 UTC (permalink / raw)


On May 19, 4:35 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> How would you use this strategy to make a controlled stream (derived
> from Root_Stream_Type)?

package P is
   type T is new Root_Stream_Type with private;
   procedure Op (O : not null access T);  -- or whatever
private
   type Control_Type (O : not null access T) is
     new Limited_Controlled with null record;

   -- override Init and Final as req'd

   type T is new Root_Stream_Type with record
      Control : Control_Type (T'Access);
      -- other components as req'd
   end record;
end P;



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  8:39                   ` Maciej Sobczak
@ 2008-05-19 15:37                     ` Matthew Heaney
  2008-05-19 21:21                       ` Maciej Sobczak
  0 siblings, 1 reply; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19 15:37 UTC (permalink / raw)


On May 19, 4:39 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> I've found two differences:
> 1. No support for exception-safe assignment in Ada.

It depends on how you define "exception-safe".  Assignment in Ada
makes only a "basic guarantee" wrt exception safety; that is, state is
not preserved but invariants are preserved. (State is not preserved
because finalization of the LHS happens before the assignment proper.)

Here's a helpful article that defines "basic" vs. "strong" vs. "no-
throw" guarantees:

http://www.boost.org/community/exception_safety.html


> 2. Memory leak after exception is raised while initializing the
> allocated object in Ada.

If by "initializing" you mean invoking a controlled action
(Initialize), then you'd get Propgram_Error, which means you have a
broken program anyway.

I do forget the exact rules about memory reclaimation, though; if I do
this:

declare
  P : T_Access := new T;
begin

and the initialization of the object designed by P fails (e.g. because
controlled initialization fails, which raises Program_Error, or
because component initialization fails, which raises
Constraint_Error), then what does the language say about reclaiming
the memory allocated for P.all?  Good question...



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 15:11       ` Matthew Heaney
@ 2008-05-19 21:13         ` Maciej Sobczak
  2008-05-23 23:03         ` Robert A Duff
  1 sibling, 0 replies; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-19 21:13 UTC (permalink / raw)


On 19 Maj, 17:11, Matthew Heaney <mhea...@on2.com> wrote:

> > How would you use this strategy to make a controlled stream (derived
> > from Root_Stream_Type)?
>
> package P is
>    type T is new Root_Stream_Type with private;
>    procedure Op (O : not null access T);  -- or whatever
> private
>    type Control_Type (O : not null access T) is
>      new Limited_Controlled with null record;
>
>    -- override Init and Final as req'd
>
>    type T is new Root_Stream_Type with record
>       Control : Control_Type (T'Access);
>       -- other components as req'd
>    end record;
> end P;

Interesting idiom. Thanks!

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 15:37                     ` Matthew Heaney
@ 2008-05-19 21:21                       ` Maciej Sobczak
  2008-05-19 23:02                         ` Matthew Heaney
  0 siblings, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-19 21:21 UTC (permalink / raw)


On 19 Maj, 17:37, Matthew Heaney <mhea...@on2.com> wrote:

> > 1. No support for exception-safe assignment in Ada.
>
> It depends on how you define "exception-safe".

I meant strong safety (either all OK or nothing modified).

> Assignment in Ada
> makes only a "basic guarantee" wrt exception safety

Yes.

> (State is not preserved
> because finalization of the LHS happens before the assignment proper.)

Note also that it prevents some obvious optimizations like avoiding
memory allocator round-trip when for example short container is
assigned to a longer one, which already has enough place for RHS.

> > 2. Memory leak after exception is raised while initializing the
> > allocated object in Ada.
>
> If by "initializing" you mean invoking a controlled action

I meant initialization of components like here:

type T is record
   X : Integer := Initialize_Me;
end record;

It can be any exception other than Program_Error, including user-
defined one.

> I do forget the exact rules about memory reclaimation, though;
> if I do
> this:
>
> declare
>   P : T_Access := new T;
> begin
>
> and the initialization of the object designed by P fails (e.g. because
> controlled initialization fails, which raises Program_Error, or
> because component initialization fails, which raises
> Constraint_Error), then what does the language say about reclaiming
> the memory allocated for P.all?

The memory is lost.
OK, it is still managed by the relevant storage pool - but if the pool
itself is not dynamically scoped (or the scope is just too wide), then
it is effectively a leak.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 21:21                       ` Maciej Sobczak
@ 2008-05-19 23:02                         ` Matthew Heaney
  0 siblings, 0 replies; 70+ messages in thread
From: Matthew Heaney @ 2008-05-19 23:02 UTC (permalink / raw)


On May 19, 5:21 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> Note also that it prevents some obvious optimizations like avoiding
> memory allocator round-trip when for example short container is
> assigned to a longer one, which already has enough place for RHS.

Right.  I suppose if a strong guarantee is necessary, then you could
make the type limited and then provide an Assign operation.


> The memory is lost.
> OK, it is still managed by the relevant storage pool - but if the pool
> itself is not dynamically scoped (or the scope is just too wide), then
> it is effectively a leak.

I guess in that case you could use an indefinite type (limited or non-
limited -- it doesn't matter anymore in Ada05) and allocate the object
on the stack.

declare
  O : T := Initialize (...);
begin

In the event of an exception during initialization, the stack would
get unwound in the normal way and there would be no memory leak.

Cheers,
Matt



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 14:45     ` Brian Drummond
@ 2008-05-20  7:42       ` Maciej Sobczak
  2008-05-20 18:01         ` jayessay
  0 siblings, 1 reply; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-20  7:42 UTC (permalink / raw)


On 19 Maj, 16:45, Brian Drummond <brian_drumm...@btconnect.com> wrote:

> But a sketch answer; a lot of them seemed to be about how to discipline
> oneself to achieve various aspects of information hiding or separation
> between interface and implementation, that a better type system would
> have achieved automatically, or nearly so.

Please name these patterns - I'm still not convinced.

I have an impression that the patterns from that book have a general
benefits and do not address deficiencies of any particular language.
In other words, they are applicable to Ada as well (and to any other
object-oriented language).

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 15:27     ` Pascal Obry
  2008-05-17 16:18       ` Georg Bauhaus
@ 2008-05-20  8:01       ` Ole-Hjalmar Kristensen
  2008-05-20 10:03         ` Martin Krischik
  1 sibling, 1 reply; 70+ messages in thread
From: Ole-Hjalmar Kristensen @ 2008-05-20  8:01 UTC (permalink / raw)


The latest C standard allows you to allocate arrays with dynamically
computed size on the stack, but not C++, I believe.

-- 
   C++: The power, elegance and simplicity of a hand grenade.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-17 16:18       ` Georg Bauhaus
@ 2008-05-20  8:04         ` Ole-Hjalmar Kristensen
  0 siblings, 0 replies; 70+ messages in thread
From: Ole-Hjalmar Kristensen @ 2008-05-20  8:04 UTC (permalink / raw)


Yes, nesting is what I miss the most when I program C, C++ or Java.

-- 
   C++: The power, elegance and simplicity of a hand grenade.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-20  8:01       ` Ole-Hjalmar Kristensen
@ 2008-05-20 10:03         ` Martin Krischik
  0 siblings, 0 replies; 70+ messages in thread
From: Martin Krischik @ 2008-05-20 10:03 UTC (permalink / raw)


Ole-Hjalmar Kristensen schrieb:

> The latest C standard allows you to allocate arrays with dynamically
> computed size on the stack, but not C++, I believe.

Indeed. But AFAIK there is only one compiler with a working 
implementation of vararrays.

Martin

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-20  7:42       ` Maciej Sobczak
@ 2008-05-20 18:01         ` jayessay
  0 siblings, 0 replies; 70+ messages in thread
From: jayessay @ 2008-05-20 18:01 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> On 19 Maj, 16:45, Brian Drummond <brian_drumm...@btconnect.com> wrote:
> 
> > But a sketch answer; a lot of them seemed to be about how to discipline
> > oneself to achieve various aspects of information hiding or separation
> > between interface and implementation, that a better type system would
> > have achieved automatically, or nearly so.
> 
> Please name these patterns - I'm still not convinced.
> 
> I have an impression that the patterns from that book have a general
> benefits and do not address deficiencies of any particular language.
> In other words, they are applicable to Ada as well (and to any other
> object-oriented language).

This is not the case for dynamic languages.  Here is a decent overview
of this:

http://norvig.com/design-patterns/ppframe.htm

As Norvig points out 16 of 23 "patterns" are either completely
obviated or simpler directly within such languages.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19 15:11       ` Matthew Heaney
  2008-05-19 21:13         ` Maciej Sobczak
@ 2008-05-23 23:03         ` Robert A Duff
  2008-05-24  0:12           ` Adam Beneschan
  1 sibling, 1 reply; 70+ messages in thread
From: Robert A Duff @ 2008-05-23 23:03 UTC (permalink / raw)


Matthew Heaney <mheaney@on2.com> writes:

> On May 19, 4:35�am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>
>> How would you use this strategy to make a controlled stream (derived
>> from Root_Stream_Type)?
>
> package P is
>    type T is new Root_Stream_Type with private;
>    procedure Op (O : not null access T);  -- or whatever
> private
>    type Control_Type (O : not null access T) is
>      new Limited_Controlled with null record;
>
>    -- override Init and Final as req'd
>
>    type T is new Root_Stream_Type with record
>       Control : Control_Type (T'Access);
>       -- other components as req'd
>    end record;
> end P;

Yes, but this idiom is needed only when the Finalize of the derived type
needs to do something with the components of the parent type.  I think
that's unusual.  The more common thing is to extend a type with some
controlled components -- each component cleans up itself.  So you don't
normally need that pointer-to-containing-object.

By the way, O is a horrible name!

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-19  7:55     ` Dmitry A. Kazakov
  2008-05-19 13:18       ` Georg Bauhaus
@ 2008-05-23 23:15       ` Robert A Duff
  2008-05-24  0:45         ` Randy Brukardt
  2008-05-24  8:25         ` Dmitry A. Kazakov
  1 sibling, 2 replies; 70+ messages in thread
From: Robert A Duff @ 2008-05-23 23:15 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Sun, 18 May 2008 20:50:48 -0700 (PDT), Matthew Heaney wrote:
>
>> On May 16, 4:42�pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>>
>>> In Ada RAII is realized with controlled types. They are severely
>>> broken in that they are intrusive in the type hierarchy and they burn
>>> the whole budget for implementation inheritance,
>> 
>> No, this is wrong.  You can add in Controlled-ness as far down the
>> hierarchy as you like, by adding a controlled component.
>
> This is broken too:
>
> 1. You don't know exactly the order in which the Finalize of the controlled
> component gets called.  So if you access the container object over an
> access discriminant, that might be already invalid.

You know something about the order.  Initialize is bottom-up,
Finalize is top-down.  And when there are access discrims, the
order among subling-components is specified by the RM.

I would prefer a fully defined order, based on the declaration order.

> 2. Similarly, Initialize might be called before the container object is
> fully operational.

Same here.

> 3. Access discriminant would require controlled object to become limited,
> so must be the container.

Ada 2005 allows access discrims on nonlimited types.

> 4. The pattern is exposed to multiple inheritance diamond diagram problem,
> when such components are added independently.

I don't understand your point here.  Could you give an example of the
problem?

>> Furthermore, if you blow your budget in Ada, then you blow in C++ too,
>> since invoking Finalization in Ada is the same as invoking a dtor in C+
>
> Well, I suggest that the overhead required in C++ for maintenance virtual
> destructors should be lower than one Ada.Finalization. For example it does
> not require linked list of objects.

Ada's finalization does not require a linked list for stack-allocated
objects.  It does for heap-allocated ones.

> IMO, initialization/finalization hooks shall be definable for all types.

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-23 23:03         ` Robert A Duff
@ 2008-05-24  0:12           ` Adam Beneschan
  0 siblings, 0 replies; 70+ messages in thread
From: Adam Beneschan @ 2008-05-24  0:12 UTC (permalink / raw)


On May 23, 4:03 pm, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:

> By the way, O is a horrible name!

Well, William Sydney Porter apparently disagreed, but I suppose we're
getting slightly off-topic for this newsgroup....

                                  -- Adam



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

* Re: memory management in Ada: tedious without GC?
  2008-05-23 23:15       ` Robert A Duff
@ 2008-05-24  0:45         ` Randy Brukardt
  2008-05-24  8:25         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 70+ messages in thread
From: Randy Brukardt @ 2008-05-24  0:45 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccskw8d332.fsf@shell01.TheWorld.com...
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
...
>> Well, I suggest that the overhead required in C++ for maintenance virtual
>> destructors should be lower than one Ada.Finalization. For example it 
>> does
>> not require linked list of objects.
>
> Ada's finalization does not require a linked list for stack-allocated
> objects.  It does for heap-allocated ones.

More importantly, why would you care? If the two words of overhead per 
object is too much, then surely the overhead of a tag is too much as well 
(also two words per object) and you'll have to regress to an untagged type. 
Similarly for the runtime cost (two instructions per object).

Moreover, the heroic efforts needed to deal with finalization of abandoned 
objects in any language with exceptions (which includes both Ada and C++) is 
going to cost as much or more (surely in code size, and probably in 
execution, too) as any linked list solution.

                                         Randy.





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

* Re: memory management in Ada: tedious without GC?
  2008-05-23 23:15       ` Robert A Duff
  2008-05-24  0:45         ` Randy Brukardt
@ 2008-05-24  8:25         ` Dmitry A. Kazakov
  2008-05-24 16:14           ` Robert A Duff
  1 sibling, 1 reply; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-24  8:25 UTC (permalink / raw)


On Fri, 23 May 2008 19:15:45 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> 1. You don't know exactly the order in which the Finalize of the controlled
>> component gets called.  So if you access the container object over an
>> access discriminant, that might be already invalid.
> 
> You know something about the order.  Initialize is bottom-up,
> Finalize is top-down.  And when there are access discrims, the
> order among subling-components is specified by the RM.
> 
> I would prefer a fully defined order, based on the declaration order.

Hmm, that would be even more broken, I think. The language should not
require more than necessary to implement the programmer's intent. The order
of record components or discriminants has no semantic meaning (except when
representation clauses involved).

The compiler should be able to re-order and even remove them, as well as
initialization of. Consider a statically constrained discriminant as an
example. If the compiler could remove it, we would have the problem of
measurement units solved!

>> 4. The pattern is exposed to multiple inheritance diamond diagram problem,
>> when such components are added independently.
> 
> I don't understand your point here.  Could you give an example of the
> problem?

type A is limited tagged record ...;
type B is new A with record
   -- a controlled component here to handle finalization of A

generic
   type Some_A is new A with private;
package P is
   type C is new Some_A with record
      -- a controlled component here to handle finalization of A

Now, if P is instantiated with B, finalization of A will be handled twice.

The problem is that finalization in C++ terms is a "virtual" member, while
record components are "non-virtual". Implementation of one through another
is IMO fundamentally broken.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24  8:25         ` Dmitry A. Kazakov
@ 2008-05-24 16:14           ` Robert A Duff
  2008-05-24 19:04             ` Dmitry A. Kazakov
  2008-05-24 19:39             ` Georg Bauhaus
  0 siblings, 2 replies; 70+ messages in thread
From: Robert A Duff @ 2008-05-24 16:14 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 23 May 2008 19:15:45 -0400, Robert A Duff wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> 1. You don't know exactly the order in which the Finalize of the controlled
>>> component gets called.  So if you access the container object over an
>>> access discriminant, that might be already invalid.
>> 
>> You know something about the order.  Initialize is bottom-up,
>> Finalize is top-down.  And when there are access discrims, the
>> order among subling-components is specified by the RM.
>> 
>> I would prefer a fully defined order, based on the declaration order.
>
> Hmm, that would be even more broken, I think. The language should not
> require more than necessary to implement the programmer's intent.

How does the compiler know the programmer's intent?  Maybe order is
important, maybe not.

>...The order
> of record components or discriminants has no semantic meaning (except when
> representation clauses involved).

It sometimes has meaning -- that's why we have positional-notation
record aggregates.

> The compiler should be able to re-order and even remove them,...

You mean lay them out in memory?  Sure, the compiler should choose an
efficient layout, which is not necessarily the same as the declaration
order.  That's OK, because record layout is invisible, except when
you're doing low-level stuff (e.g. interfacing to something outside
the Ada world).

>... as well as
> initialization of.

There, I disagree.  I see zero advantage to allowing arbitrary order for
the calls to Initialize and Finalize.  And one huge disadvantage -- if
you depend on the order, either on purpose or by accident, you might get
a bug introduced years later, when you switch compilers (or even
compiler versions).  It will be very hard to detect and to fix that
bug!

Consider two finalization actions -- one flushes a buffer to disk,
and the other closes the file handle.

>... Consider a statically constrained discriminant as an
> example. If the compiler could remove it, we would have the problem of
> measurement units solved!

Yes.  I've always wanted to do that optimization.

The strange thing is that most compilers do exactly that for array
bounds, but not for discriminants.  Array bounds are really
discriminants, deep down!  ;-)

>>> 4. The pattern is exposed to multiple inheritance diamond diagram problem,
>>> when such components are added independently.
>> 
>> I don't understand your point here.  Could you give an example of the
>> problem?
>
> type A is limited tagged record ...;
> type B is new A with record
>    -- a controlled component here to handle finalization of A
>
> generic
>    type Some_A is new A with private;
> package P is
>    type C is new Some_A with record
>       -- a controlled component here to handle finalization of A
>
> Now, if P is instantiated with B, finalization of A will be handled twice.
>
> The problem is that finalization in C++ terms is a "virtual" member, while
> record components are "non-virtual". Implementation of one through another
> is IMO fundamentally broken.

OK, I understand the above example (although I don't see a diamond).

My answer is, "So don't do that".  ;-)

Why would you put the finalization for A in B?  Put it in A where it
belongs.  The main reason to add finalization to B is if B adds
new components that need to be cleaned up.  If so, then wrap
those components in a controlled type.

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24 16:14           ` Robert A Duff
@ 2008-05-24 19:04             ` Dmitry A. Kazakov
  2008-05-24 20:52               ` Robert A Duff
  2008-05-24 19:39             ` Georg Bauhaus
  1 sibling, 1 reply; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-24 19:04 UTC (permalink / raw)


On Sat, 24 May 2008 12:14:56 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Fri, 23 May 2008 19:15:45 -0400, Robert A Duff wrote:
>>
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>> 
>>>> 1. You don't know exactly the order in which the Finalize of the controlled
>>>> component gets called.  So if you access the container object over an
>>>> access discriminant, that might be already invalid.
>>> 
>>> You know something about the order.  Initialize is bottom-up,
>>> Finalize is top-down.  And when there are access discrims, the
>>> order among subling-components is specified by the RM.
>>> 
>>> I would prefer a fully defined order, based on the declaration order.
>>
>> Hmm, that would be even more broken, I think. The language should not
>> require more than necessary to implement the programmer's intent.
> 
> How does the compiler know the programmer's intent?  Maybe order is
> important, maybe not.

Yes, this why it is safe to assume that the program may not rely on it.

>>...The order
>> of record components or discriminants has no semantic meaning (except when
>> representation clauses involved).
> 
> It sometimes has meaning -- that's why we have positional-notation
> record aggregates.

Just a lexical convention to me.

>>... as well as
>> initialization of.
> 
> There, I disagree.  I see zero advantage to allowing arbitrary order for
> the calls to Initialize and Finalize.  And one huge disadvantage -- if
> you depend on the order, either on purpose or by accident, you might get
> a bug introduced years later, when you switch compilers (or even
> compiler versions).  It will be very hard to detect and to fix that
> bug!

Yes, this is the same dilemma as with re-ordering operands in expressions.
I understand your argument, but I think that the solution is wrong. I'd
prefer a better control over the side effects in order to make such
(erroneous) programs illegal. It is especially important for modern
pipelined, multi-core architectures. Why not to perform initialization of
components concurrently?

> Consider two finalization actions -- one flushes a buffer to disk,
> and the other closes the file handle.

It is a wrong design to handle this from components and from different
actions of finalization. Buffer cannot be flushed without knowing the file
handle. Thus with right design the buffer component will have no access to
the file handle. Hence flushing could only be put into the finalization of
the composite object, which would automatically enforce proper order.

>>... Consider a statically constrained discriminant as an
>> example. If the compiler could remove it, we would have the problem of
>> measurement units solved!
> 
> Yes.  I've always wanted to do that optimization.
> 
> The strange thing is that most compilers do exactly that for array
> bounds, but not for discriminants.  Array bounds are really
> discriminants, deep down!  ;-)

Yes, and don't forget type tags. They are discriminants too!

>>>> 4. The pattern is exposed to multiple inheritance diamond diagram problem,
>>>> when such components are added independently.
>>> 
>>> I don't understand your point here.  Could you give an example of the
>>> problem?
>>
>> type A is limited tagged record ...;
>> type B is new A with record
>>    -- a controlled component here to handle finalization of A
>>
>> generic
>>    type Some_A is new A with private;
>> package P is
>>    type C is new Some_A with record
>>       -- a controlled component here to handle finalization of A
>>
>> Now, if P is instantiated with B, finalization of A will be handled twice.
>>
>> The problem is that finalization in C++ terms is a "virtual" member, while
>> record components are "non-virtual". Implementation of one through another
>> is IMO fundamentally broken.
> 
> OK, I understand the above example (although I don't see a diamond).

  A
 /  \
B   C (generic)
 \  /
  C (instance)

> My answer is, "So don't do that".  ;-)

I thought Ada is a safe language (:-)) Seriously, I think that the Rosen
trick should be made illegal for controlled components. It is unsafe.

> Why would you put the finalization for A in B?  Put it in A where it
> belongs.

Exactly, but I cannot if A is not controlled!

> The main reason to add finalization to B is if B adds
> new components that need to be cleaned up.  If so, then wrap
> those components in a controlled type.

This is not the only case. There is a different case when B adds new
functionality rather than components. This might require some book keeping
actions upon initialization and finalization. These actions cannot be
expressed in the terms of individual components, but in primitive
operations of A/B. This is the notorious dispatching from
constructor/destructor. I call it "class-wide" initialization/finalization.

The Rosen trick on a controlled component emulates such class-wide
initialization/finalization. But defining an order of component
initialization does not save it. Because if you derived from that type, new
components would be initialized after the inherited controlled one. So
dispatching from its initialization to an overridden operation would become
a disaster.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24 16:14           ` Robert A Duff
  2008-05-24 19:04             ` Dmitry A. Kazakov
@ 2008-05-24 19:39             ` Georg Bauhaus
  2008-05-24 20:45               ` Robert A Duff
  1 sibling, 1 reply; 70+ messages in thread
From: Georg Bauhaus @ 2008-05-24 19:39 UTC (permalink / raw)


Robert A Duff wrote:
> I see zero advantage to allowing arbitrary order for
> the calls to Initialize and Finalize.  And one huge disadvantage -- if
> you depend on the order, either on purpose or by accident, you might get
> a bug introduced years later, when you switch compilers (or even
> compiler versions).  It will be very hard to detect and to fix that
> bug!

OTOH, defining finalization order just by referring to
the order of components in the source text seem the weakest
mode of expression.  It is also in the way of ordering
components in source text by grouping criteria unrelated
to finalization.

When finalization order is important, couldn't the language
enable the programmer to just state the order?

  for T'Finalization_Order use
    record
      Component_1;
      Component_3;
      select
         Component_4 or Component_5;
      end select;
      Component_6;
    end record;


The "or" would mean any order is fine.
Omitting a component would mean the compiler is free to choose
when to finalize.



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24 19:39             ` Georg Bauhaus
@ 2008-05-24 20:45               ` Robert A Duff
  0 siblings, 0 replies; 70+ messages in thread
From: Robert A Duff @ 2008-05-24 20:45 UTC (permalink / raw)


Georg Bauhaus <see.reply.to@maps.futureapps.de> writes:

> Robert A Duff wrote:
>> I see zero advantage to allowing arbitrary order for
>> the calls to Initialize and Finalize.  And one huge disadvantage -- if
>> you depend on the order, either on purpose or by accident, you might get
>> a bug introduced years later, when you switch compilers (or even
>> compiler versions).  It will be very hard to detect and to fix that
>> bug!
>
> OTOH, defining finalization order just by referring to
> the order of components in the source text seem the weakest
> mode of expression.  It is also in the way of ordering
> components in source text by grouping criteria unrelated
> to finalization.

Well, when I write:

    procedure P (...) is
        This : ...;
        That : ...;
    begin
        ...
    end P;

This and That are initialized in order, and finalized in reverse order.
I don't find that strange.  So why shouldn't record components
be the same?

> When finalization order is important, couldn't the language
> enable the programmer to just state the order?
>
>   for T'Finalization_Order use
>     record
>       Component_1;
>       Component_3;
>       select
>          Component_4 or Component_5;
>       end select;
>       Component_6;
>     end record;

It could, but it seems like a lot of mechanism.

Part of my point is that you might write a program that depends on
finalization order by accident.  You write the program, test it, and it
does what you want.  You don't want the order to change in the future,
but since it's by accident, you can't be expected to write
"for T'Fin_Order...".

> The "or" would mean any order is fine.
> Omitting a component would mean the compiler is free to choose
> when to finalize.

I can't think of any advantage to allowing the compiler to choose the
order.

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24 19:04             ` Dmitry A. Kazakov
@ 2008-05-24 20:52               ` Robert A Duff
  2008-05-25  8:12                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 70+ messages in thread
From: Robert A Duff @ 2008-05-24 20:52 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> Yes, this why it is safe to assume that the program may not rely on it.

Such assumptions are never safe, because programmers make mistakes.

> Yes, this is the same dilemma as with re-ordering operands in expressions.

I don't like the permission to reorder operands, either.
But at least for that, there's a legitimate efficiency concern.
For finalization, I seriously doubt that the permission
to reorder has any significant efficiency benefit.

> I understand your argument, but I think that the solution is wrong. I'd
> prefer a better control over the side effects in order to make such
> (erroneous) programs illegal. It is especially important for modern
> pipelined, multi-core architectures. Why not to perform initialization of
> components concurrently?

Sure, if the compiler can prove there are no side effects,
it can reorder, intersperse, and/or do things in parallel.
In that case, "in declaration order" and "in implementation-defined
order" are equivalent rules.

But this is a much bigger change to Ada.

>> Consider two finalization actions -- one flushes a buffer to disk,
>> and the other closes the file handle.
>
> It is a wrong design to handle this from components and from different
> actions of finalization. Buffer cannot be flushed without knowing the file
> handle. Thus with right design the buffer component will have no access to
> the file handle. Hence flushing could only be put into the finalization of
> the composite object, which would automatically enforce proper order.

I admit my example is weak.

>>>... Consider a statically constrained discriminant as an
>>> example. If the compiler could remove it, we would have the problem of
>>> measurement units solved!
>> 
>> Yes.  I've always wanted to do that optimization.
>> 
>> The strange thing is that most compilers do exactly that for array
>> bounds, but not for discriminants.  Array bounds are really
>> discriminants, deep down!  ;-)
>
> Yes, and don't forget type tags. They are discriminants too!

Right.

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-24 20:52               ` Robert A Duff
@ 2008-05-25  8:12                 ` Dmitry A. Kazakov
  2008-05-25 11:28                   ` Maciej Sobczak
  2008-05-25 12:35                   ` Robert A Duff
  0 siblings, 2 replies; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-25  8:12 UTC (permalink / raw)


On Sat, 24 May 2008 16:52:03 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> Yes, this why it is safe to assume that the program may not rely on it.
> 
> Such assumptions are never safe, because programmers make mistakes.

That is why Ada should be picky. I prefer to qualify such programs as
erroneous and allow the compiler to reject them. This is independent on
whether we would fix the order or not.

>> Yes, this is the same dilemma as with re-ordering operands in expressions.
> 
> I don't like the permission to reorder operands, either.
> But at least for that, there's a legitimate efficiency concern.
> For finalization, I seriously doubt that the permission
> to reorder has any significant efficiency benefit.

type X is record
   A : Boolean := False;
   B : Integer := 1;
   C : Boolean := False;
end record;

May the compiler group A and C and initialize both them by zeroing memory?
If the initialization order were fixed, that would be illegal to do.

>> I understand your argument, but I think that the solution is wrong. I'd
>> prefer a better control over the side effects in order to make such
>> (erroneous) programs illegal. It is especially important for modern
>> pipelined, multi-core architectures. Why not to perform initialization of
>> components concurrently?
> 
> Sure, if the compiler can prove there are no side effects,
> it can reorder, intersperse, and/or do things in parallel.
> In that case, "in declaration order" and "in implementation-defined
> order" are equivalent rules.

Yes, this could be the ground for a compromise. Let us introduce pure
subprograms, not as a pragma Pure, but as a contract.

Now, the components are initialized by pure subprograms can be in any order
when they are siblings. Others are initialized in their declaration order. 

> But this is a much bigger change to Ada.

The compiler would not need to prove anything. That would be the
programmer's responsibility to ensure purity of an implementation. Of
course, a decent compiler would make some reasonable checks, but it would
be sufficient to verify that pure bodies do not call impure ones. Surely, a
pure primitive operation could not be overridden by an impure one, etc.
That does not look much intrusive.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-25  8:12                 ` Dmitry A. Kazakov
@ 2008-05-25 11:28                   ` Maciej Sobczak
  2008-05-25 12:35                   ` Robert A Duff
  1 sibling, 0 replies; 70+ messages in thread
From: Maciej Sobczak @ 2008-05-25 11:28 UTC (permalink / raw)


On 25 Maj, 10:12, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> type X is record
>    A : Boolean := False;
>    B : Integer := 1;
>    C : Boolean := False;
> end record;
>
> May the compiler group A and C and initialize both them by zeroing memory?
> If the initialization order were fixed, that would be illegal to do.

If there are no side effects (like I/O) associated with initialization
of individual components, then you have no possibility to verify what
is the actual order and the compiler should be allowed to do whatever
it wants.

Fixing the order of initialization and leaving some margin for
optimizations do not conflict with each other.

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



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

* Re: memory management in Ada: tedious without GC?
  2008-05-25  8:12                 ` Dmitry A. Kazakov
  2008-05-25 11:28                   ` Maciej Sobczak
@ 2008-05-25 12:35                   ` Robert A Duff
  2008-05-26  8:16                     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 70+ messages in thread
From: Robert A Duff @ 2008-05-25 12:35 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> type X is record
>    A : Boolean := False;
>    B : Integer := 1;
>    C : Boolean := False;
> end record;
>
> May the compiler group A and C and initialize both them by zeroing memory?

Yes.

> If the initialization order were fixed, that would be illegal to do.

No -- it's perfectly legal for the compiler to initialize in any order
here, because the order does not affect the semantics (and it's easy for
the compiler to prove that).

For example, the compiler could lay out the above so that A and C
are allocated in the same word, and initialize by "move 1 into B"
then "move 0 into A,C".  That's true in Ada, and it's also true
in this imaginary "Ada with init in decl order rule".

- Bob



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

* Re: memory management in Ada: tedious without GC?
  2008-05-25 12:35                   ` Robert A Duff
@ 2008-05-26  8:16                     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 70+ messages in thread
From: Dmitry A. Kazakov @ 2008-05-26  8:16 UTC (permalink / raw)


On Sun, 25 May 2008 08:35:02 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> type X is record
>>    A : Boolean := False;
>>    B : Integer := 1;
>>    C : Boolean := False;
>> end record;
>>
>> May the compiler group A and C and initialize both them by zeroing memory?
> 
> Yes.
> 
>> If the initialization order were fixed, that would be illegal to do.
> 
> No -- it's perfectly legal for the compiler to initialize in any order
> here, because the order does not affect the semantics (and it's easy for
> the compiler to prove that).

In this case. But there could be much more complex cases with user-defined
initialization involved. There should be a clear rule to determine if the
semantics is order-independent. This semantics should follow from the
contracts, rather than from the implementation.

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



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

end of thread, other threads:[~2008-05-26  8:16 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-16 17:44 memory management in Ada: tedious without GC? jhc0033
2008-05-16 18:56 ` Ludovic Brenta
2008-05-16 20:42 ` Maciej Sobczak
2008-05-16 21:45   ` Ivan Levashew
2008-05-16 22:59   ` Peter C. Chapin
2008-05-17  5:24     ` jhc0033
2008-05-17  7:50       ` Ivan Levashew
2008-05-16 23:05   ` Randy Brukardt
2008-05-19  3:50   ` Matthew Heaney
2008-05-19  7:55     ` Dmitry A. Kazakov
2008-05-19 13:18       ` Georg Bauhaus
2008-05-19 14:16         ` Dmitry A. Kazakov
2008-05-23 23:15       ` Robert A Duff
2008-05-24  0:45         ` Randy Brukardt
2008-05-24  8:25         ` Dmitry A. Kazakov
2008-05-24 16:14           ` Robert A Duff
2008-05-24 19:04             ` Dmitry A. Kazakov
2008-05-24 20:52               ` Robert A Duff
2008-05-25  8:12                 ` Dmitry A. Kazakov
2008-05-25 11:28                   ` Maciej Sobczak
2008-05-25 12:35                   ` Robert A Duff
2008-05-26  8:16                     ` Dmitry A. Kazakov
2008-05-24 19:39             ` Georg Bauhaus
2008-05-24 20:45               ` Robert A Duff
2008-05-19  8:35     ` Maciej Sobczak
2008-05-19 15:11       ` Matthew Heaney
2008-05-19 21:13         ` Maciej Sobczak
2008-05-23 23:03         ` Robert A Duff
2008-05-24  0:12           ` Adam Beneschan
2008-05-16 22:45 ` anon
2008-05-17  7:34 ` Pascal Obry
2008-05-17 15:11   ` Bob Klungle
2008-05-17 15:27     ` Pascal Obry
2008-05-17 16:18       ` Georg Bauhaus
2008-05-20  8:04         ` Ole-Hjalmar Kristensen
2008-05-20  8:01       ` Ole-Hjalmar Kristensen
2008-05-20 10:03         ` Martin Krischik
2008-05-17 17:23     ` Martin Krischik
2008-05-17 16:51   ` Maciej Sobczak
2008-05-17 17:45     ` Pascal Obry
2008-05-17 22:28       ` Samuel Tardieu
2008-05-18  7:03         ` Martin Krischik
2008-05-18  8:50           ` jhc0033
2008-05-18  9:31             ` Dmitry A. Kazakov
2008-05-18 14:10               ` Maciej Sobczak
2008-05-18 14:59                 ` Dmitry A. Kazakov
2008-05-18 20:51                   ` Maciej Sobczak
2008-05-19  8:36                     ` Dmitry A. Kazakov
2008-05-18 15:03             ` Martin Krischik
2008-05-18 18:27               ` jhc0033
2008-05-19  4:12                 ` Matthew Heaney
2008-05-19  8:39                   ` Maciej Sobczak
2008-05-19 15:37                     ` Matthew Heaney
2008-05-19 21:21                       ` Maciej Sobczak
2008-05-19 23:02                         ` Matthew Heaney
2008-05-19 10:27                 ` Martin Krischik
2008-05-17 22:42       ` Peter C. Chapin
2008-05-18  6:58         ` Martin Krischik
2008-05-18  6:52     ` Martin Krischik
2008-05-18 14:16       ` Maciej Sobczak
2008-05-17 14:30 ` Brian Drummond
2008-05-17 16:47   ` Maciej Sobczak
2008-05-19 14:45     ` Brian Drummond
2008-05-20  7:42       ` Maciej Sobczak
2008-05-20 18:01         ` jayessay
2008-05-18  8:06   ` Simon Wright
2008-05-18 14:21     ` Maciej Sobczak
2008-05-18 20:48       ` Simon Wright
2008-05-19 14:40     ` Brian Drummond
2008-05-19  3:44 ` Matthew Heaney

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