My Language Feature Requests

Craig Black craigblack2 at cox.net
Sun Dec 23 21:31:49 PST 2007


"Christopher Wright" <dhasenan at gmail.com> wrote in message 
news:fkmoj4$k0u$1 at digitalmars.com...
> Craig Black wrote:
>>> Polymorphic structs *have* to be reference types, unless you determine 
>>> stack layout at runtime. And not only that, you have to modify stack 
>>> layout after you've created a stack frame. The only saving grace is that 
>>> you won't have to do that for a stack frame higher than the current one.
>>
>> Right, but that's not a problem if you disallow polymorphism for stack 
>> objects.  This is what C++ does and it works very well.  Rather than 
>> generating a run-time assertion, your code would simply not compile.  If 
>> you want polymorphism then you have to instantiate then you would have to 
>> instantiate the struct on the heap.
>
> Ideally you'd determine whether your polymorphic struct has inheritors or 
> base classes and, if so, put it on the heap, else put it on the stack.

That's the approach for both C++ structs and classes.  But this decision is 
made by the programmer, not the compiler.  I don't see how the compiler 
could do this, since it is impossible to have knowledge of subclasses that 
exist in an external library.  The compiler would have to revert to a worst 
case, and put everything on the heap.

> This is why it'd be better to keep structs as they are, but have by-value 
> classes.

By-value classes is just another way to do the same thing, but inferior IMO.

>> Anyway, this is all moot anyway, because I've thought of an easier 
>> solution. Pointers can be checked at run-time to determine if they 
>> address the GC heap.  This check could be removed when compiling in 
>> release mode, so there will be no performance degradation.
>
> That's the current system, and it's basically what I've been saying all 
> this time. I guess I was unclear. But you can't remove the check in 
> release mode:

Jeez.  It's like we've been speaking two different languages the whole time. 
I'm not talking about turning off the garbage collector in release mode. 
I'm talking about run-time checks that prohibit raw pointers from pointing 
to the GC heap.  The same thing you said should be "undefined behavior". 
Thus, it would be undefined behavior in release mode, but in debug mode 
there would be a check.  Like array bounds-checking.

>> So there's no need to dissallow new and delete for classes and we don't 
>> need struct polymorphism.
>
> Well, we don't need any kind of polymorphism, but quite separate from the 
> rest of the requests, struct polymorphism would be useful. Though I 
> wouldn't refer to them as structs if they're polymorphic, since you really 
> can't put them on the stack, and so they have to be reference types with 
> value semantics.

Sorry, but I don't see the novelty of "reference types with value 
semantics".  What would it be useful for?  The reason I am pushing 
improvements to structs is that I know it will allow for more versatile 
aggregate types that aren't allocated on the heap.  It's important that they 
are not allocated on the heap because that is more efficient.  From my 
perspective, your proposal does nothing for performance, since there is 
still a heap allocation.

>>> You're saying:
>>> class Foo {
>>>    int i;
>>> }
>>>
>>> Foo f = new Foo();
>>> int* i_ptr = &f.i;
>>>
>>> That would be a compile error? f is not fixed; I don't care if the bits 
>>> in i_ptr change, or the bits in the reference f. Why should I?
>>>
>>> Just because I took the address of f.i and stored it in an unfixed 
>>> pointer, the garbage collector, which has full authority to change the 
>>> pointer I just got, can't move *f?
>>>
>>> Why?
>>
>> I'm not really sure what you are asking.  If the GC moves the relocates 
>> f, then i_ptr no longer points the appropriate location.  Isn't that 
>> obvious?
>>
>> Are you suggesting that the GC relocate i_ptr as well?  No GC I know of 
>> relocates raw pointers, so there's probably a good technical reason why 
>> they don't.  I'm not a GC expert though.
>
> Because no language besides D allows you to take the address of an class 
> member and has native garbage collection, and D doesn't have a moving 
> collector. There's the Boehm collector for C++, but that's not a moving 
> collector. C# has unsafe blocks in which you can use pointers, but in 
> those blocks you don't have a garbage collector running. And...that's it. 
> Maybe we'll see something revolutionary with Objective-C 2.0, but probably 
> not, and it's not here yet.
>
> You're already moving raw pointers, so you may as well move all of them. 
> Otherwise you're eliminating a decently general use case or causing random 
> segfaults or losing a lot of efficiency in memory layout (which will make 
> future collections quicker, too) for pretty much nothing.

Heck, you may be right about this.  Like I said I'm no GC expert. 




More information about the Digitalmars-d mailing list