September 08, 2001
Russ Lewis wrote in message <3B97CEF7.6223A784@deming-os.org>...
>This (in cooperation with garbage collection) is going to be *really* nice
for
>regular expressions.  You can just return a dynamic array that is a subset
of
>another string.  Since strings are not null terminated in D, no copying is needed!


Being able to "map" arrays onto other arrays, no copying necessary, can result in some large performance boosts over the traditional way of doing C strings.


September 08, 2001
Charles Hixson wrote in message <3B98DD7E.6030905@earthlink.net>...
>Thanks, that sounds like *just* what I was asking for!  (And a
>bit more, as it can be passed as a parameter.)  (And a bit less,
>as the original string isn't "safe" from the references.)


There is a bit of a dark side to this. The trouble is that resizing a dynamic array has the semantics of a "realloc". This means it can be copied, but might not be. Thus, if you are holding another reference to the same array, you can get indeterminate behavior:

    char foo[];
    foo = new char[50];
    foo[6] = 'b';
    char bar[] = foo;    // foo and bar point to the same data
    bar.length = 55;    // now foo and bar may or may not point to the same
data
    bar[6] = 'a';            // is foo[6] now 'a' or 'b'?

Now, foo's data won't be free'd, because the gc will find it is still pointed to by foo, so at least this won't produce a pointer bug. If anyone has a good solution to this problem, I'd like to hear it. I don't want to make a resize into an "always copy" semantics, for performance reasons.


September 08, 2001
Walter wrote:

> 
> Axel Kittenberger wrote in message <9nbaf7$1q6m$1@digitaldaemon.com>...
>>Well but you know that in operating systems kernel you don't have a malloc or a free?
> 
> So don't use dynamic arrays for such code. Nothing prevents you from using
> my_malloc() and my_free().

However beeing able to create objects on stack is essential in some tougher cases :/

September 08, 2001
You can still create struct's on the stack.

Axel Kittenberger wrote in message <9ncq4u$2mof$1@digitaldaemon.com>... Walter wrote:

>
> Axel Kittenberger wrote in message <9nbaf7$1q6m$1@digitaldaemon.com>...
>>Well but you know that in operating systems kernel you don't have a malloc or a free?
>
> So don't use dynamic arrays for such code. Nothing prevents you from using
> my_malloc() and my_free().

However beeing able to create objects on stack is essential in some tougher cases :/



September 08, 2001
Walter wrote:

> You can still create struct's on the stack.

Oh sorry, then I took it up wrong from another tread :/ Thought you mentioned that all objects are created on the heap, no more stack objects.


September 08, 2001
Axel Kittenberger wrote in message <9ndjvd$4fa$1@digitaldaemon.com>...
>Walter wrote:
>> You can still create struct's on the stack.
>>Oh sorry, then I took it up wrong from another tread :/ Thought you mentioned that all objects are created on the heap, no more stack objects.

Structs can be created on the heap, the static data segment, or on the stack. Classes, however, can only be created on the garbage collected heap.

The reason for the latter is to avoid all the complications with copy constructors, assignment operators, trying to hang the destructors on all exits from scope, etc.




September 08, 2001
> Structs can be created on the heap, the static data segment, or on the stack. Classes, however, can only be created on the garbage collected heap.
> 
> The reason for the latter is to avoid all the complications with copy constructors, assignment operators, trying to hang the destructors on all exits from scope, etc.

Isn't the guaranteed destruction calls advertised as a major feature of C++? A lot of people even wrap certain resource binding into classes just to be sure they get freed again with destruction, when the caller leaves the scope.
September 08, 2001
Walter wrote:
> 
> Charles Hixson wrote in message <3B98DD7E.6030905@earthlink.net>...
> >Thanks, that sounds like *just* what I was asking for!  (And a
> >bit more, as it can be passed as a parameter.)  (And a bit less,
> >as the original string isn't "safe" from the references.)
> 
> There is a bit of a dark side to this. The trouble is that resizing a dynamic array has the semantics of a "realloc". This means it can be copied, but might not be. Thus, if you are holding another reference to the same array, you can get indeterminate behavior:
> 
>     char foo[];
>     foo = new char[50];
>     foo[6] = 'b';
>     char bar[] = foo;    // foo and bar point to the same data
>     bar.length = 55;    // now foo and bar may or may not point to the same
> data
>     bar[6] = 'a';            // is foo[6] now 'a' or 'b'?
> 
> Now, foo's data won't be free'd, because the gc will find it is still pointed to by foo, so at least this won't produce a pointer bug. If anyone has a good solution to this problem, I'd like to hear it. I don't want to make a resize into an "always copy" semantics, for performance reasons.

	I wish I had an answer, and I'm afraid I might make things worse.  What
happens here?

	char foo[];
	foo = "Hi there!";              // 9 character string
	char bar[] = foo;               // we share it
	foo.length = foo.length - 1;    // now foo is 8 char, possibly a word
boundary
	bar[8];                         // could this now be unallocated space?

I guess I'm not sure of the specifics here, but it seems that after a decrease in size, that a part of unallocated or (worse) reallocated memory could still be accessed.  My best guess here is to never actually shrink the allocated memory whether or not it is unused, but that could create other nasty memory leaks.

Dan
September 08, 2001
Axel Kittenberger wrote in message <9ndn49$5ve$1@digitaldaemon.com>...
>Isn't the guaranteed destruction calls advertised as a major feature of C++? A lot of people even wrap certain resource binding into classes just to be sure they get freed again with destruction, when the caller leaves the scope.

Yes, that is the C++ paradigm. Most of the resource freeing is simply memory deallocation, which is handled by the garbage collector in D. The rest can be handled with a finally block.


September 08, 2001
Walter wrote:

> 
> Axel Kittenberger wrote in message <9ndn49$5ve$1@digitaldaemon.com>...
>>Isn't the guaranteed destruction calls advertised as a major feature of C++? A lot of people even wrap certain resource binding into classes just to be sure they get freed again with destruction, when the caller leaves the scope.
> 
> Yes, that is the C++ paradigm. Most of the resource freeing is simply memory deallocation, which is handled by the garbage collector in D. The rest can be handled with a finally block.

Okay I understand.

Well but on question, let's take in example a File stream class. Say I
created for local use only like
{
   File a("cork");
   try {
      a.open();
   } catch FileNotFoundException() {
      printf("File 'cork' not found\n");
      exit(-1);
   }
   a.write("bork");
}

So the file descriptior a uses is a (limited) resource. No matter what will happen, sooner or later when the code moves out of context the resource is freed. Now I guess the file descriptior for 'a' will then stay open, right? Normally C++ classes close it's file descriptor if they were forgotten to left open.

Other question if the close fails, a FileIOException should be raised, so are finalizers allowed raise exceptions? I think in combination with a GC this is nearly impossibile, since the exception would be raised you anywhere from where the code currently executes.

- Axel