Jump to page: 1 2 3
Thread overview
D vs. placement new (for classes) aka why D needs .sizeof and .alignof for classes (values not references)
Apr 12, 2007
Forest Ray
Apr 13, 2007
torhu
Re: D vs. placement new (for classes) aka why D needs .sizeof and
Apr 13, 2007
Forest Ray
Apr 13, 2007
Sean Kelly
Re: D vs. placement new (for classes) aka why D needs .sizeof and
Apr 13, 2007
Dan
Apr 13, 2007
Sean Kelly
Apr 14, 2007
David B. Held
Apr 14, 2007
David B. Held
Apr 16, 2007
Dan
Apr 16, 2007
Daniel Keep
Re: D vs. placement new (for classes) aka why D needs .sizeof and
Apr 16, 2007
Dan
Apr 17, 2007
Lars Ivar Igesund
Apr 17, 2007
Dan
April 12, 2007
Before I add this to the bug database I wanted to run this by everyone and see if I'm overlooking something.  Classes in D are always a reference.  Therefore the .sizeof and .alignof a class (reference) are always (void*).sizeof and (void*).alignof.  D allows the class allocator (new) to be overloaded.  The number of bytes required to hold the class (value) is passed as the first parameter to new(size_t size).  This works well unless you are wanting to perform a placement new.  When using placement new you pass in the storage for the object to be placed.

new(size_t size, void* ptr) {
    return ptr;
}

The problem is at compile time you can NOT determine the size or alignment of a class (value), only the reference.  Therefore you can not know the sizeof the buffer to preallocate to hold the class (value).  I believe this to be an oversight in the language design.  The alignment issue is easier to overcome, the ABI states the first field of a class (value) is the vbtbl pointer which will always mean the class (value) is (void*).alignof aligned.  The .sizeof property for a class (value) is not available, here in lies the problem.  Placement new is the easy example where the sizeof the class (value) is needed.  Also consider the case of a blocks of class (values) being preallocated for a free list.

April 13, 2007
Forest Ray wrote:
> Before I add this to the bug database I wanted to run this by everyone and see if I'm overlooking something.  Classes in D are always a reference.  Therefore the .sizeof and .alignof a class (reference) are always (void*).sizeof and (void*).alignof.  D allows the class allocator (new) to be overloaded.  The number of bytes required to hold the class (value) is passed as the first parameter to new(size_t size).  This works well unless you are wanting to perform a placement new.  When using placement new you pass in the storage for the object to be placed.  
> 
> new(size_t size, void* ptr) {
>     return ptr;
> }
> 
> The problem is at compile time you can NOT determine the size or alignment of a class (value), only the reference.  Therefore you can not know the sizeof the buffer to preallocate to hold the class (value).  I believe this to be an oversight in the language design.  The alignment issue is easier to overcome, the ABI states the first field of a class (value) is the vbtbl pointer which will always mean the class (value) is (void*).alignof aligned.  The .sizeof property for a class (value) is not available, here in lies the problem.  Placement new is the easy example where the sizeof the class (value) is needed.  Also consider the case of a blocks of class (values) being preallocated for a free list.
> 

Given:
class Foo { ... }
auto obj = new Foo;

There is:
obj.sizeof

Which you know, and does as you say.  But then there is:
obj.classinfo.init.sizeof

Which will render the actual size of class instances.  :)  Granted it isn't very pretty, but it works.  What _would_ be nifty, would be if one could use 'Foo.sizeof' (invoke .sizeof on the type rather than the variable) to get the same value.  Ie, make Class.sizeof an alias to Class.classinfo.init.sizeof -- I don't think this would be a problem.  In the meantime, the .classinfo trick is your friend.

-- Chris Nicholson-Sauls
April 13, 2007
> Which you know, and does as you say.  But then there is: obj.classinfo.init.sizeof
> 
> Which will render the actual size of class instances.  :)

no, it doesn't :)
April 13, 2007
Frank Benoit (keinfarbton) wrote:
>> Which you know, and does as you say.  But then there is:
>> obj.classinfo.init.sizeof
>> 
>> Which will render the actual size of class instances.  :)
> 
> no, it doesn't :)

obj.classinfo.init.length is documented as 'init.length gives size in bytes of class'.
April 13, 2007
torhu schrieb:
> Frank Benoit (keinfarbton) wrote:
>>> Which you know, and does as you say.  But then there is: obj.classinfo.init.sizeof
>>>
>>> Which will render the actual size of class instances.  :)
>>
>> no, it doesn't :)
> 
> obj.classinfo.init.length is documented as 'init.length gives size in bytes of class'.

well, i don't know about the size of the class, but it does not give the size of the class /instance/.
April 13, 2007
> well, i don't know about the size of the class, but it does not give the size of the class /instance/.

I was sure i had an example that shows it doesn't.
But it seems I am wrong. Sorry about that. If i find it, I file a bug
report.

Frank
April 13, 2007
Thanks for get me thinking along that path, the size of a class can be found by using CLASS.classinfo.init.length

import std.stdio;

class foo {
	int a = 1;
	int b = 2;
	int c = 3;
}

void main() {
	writefln("size = ", foo.classinfo.init.length);
}

./xxx
size = 20


Frank Benoit (keinfarbton) Wrote:

> 
> > well, i don't know about the size of the class, but it does not give the size of the class /instance/.
> 
> I was sure i had an example that shows it doesn't.
> But it seems I am wrong. Sorry about that. If i find it, I file a bug
> report.
> 
> Frank

April 13, 2007
Forest Ray wrote:
> Before I add this to the bug database I wanted to run this
> by everyone and see if I'm overlooking something.  Classes
> in D are always a reference.  Therefore the .sizeof and
> .alignof a class (reference) are always (void*).sizeof and
> (void*).alignof.  D allows the class allocator (new) to be
> overloaded.  The number of bytes required to hold the class
> (value) is passed as the first parameter to new(size_t size).
> This works well unless you are wanting to perform a placement
> new.  When using placement new you pass in the storage for
> the object to be placed.
>
> 
> new(size_t size, void* ptr) {
>     return ptr;
> }
> 
> The problem is at compile time you can NOT determine the
> size or alignment of a class (value), only the reference.
> Therefore you can not know the sizeof the buffer to
> preallocate to hold the class (value).  I believe this to be
> an oversight in the language design.  The alignment issue is
> easier to overcome, the ABI states the first field of a
> class (value) is the vbtbl pointer which will always mean
> the class (value) is (void*).alignof aligned.  The .sizeof
> property for a class (value) is not available, here in lies
> the problem.  Placement new is the easy example where the
> sizeof the class (value) is needed.  Also consider the case
> of a blocks of class (values) being preallocated for a free list.

See http://d.puremagic.com/issues/show_bug.cgi?id=88


Sean
April 13, 2007
Frank Benoit (keinfarbton) wrote:
>> Which you know, and does as you say.  But then there is:
>> obj.classinfo.init.sizeof
>>
>> Which will render the actual size of class instances.  :)
> 
> no, it doesn't :)

Note to self: sleep|eat|veg first, post later.  Ah well, at least the correct property got brought up eventually.  I'll just go punish myself now (ie, go to bed).  :)

-- Chris Nicholson-Sauls
April 13, 2007
Finally i found my testcase...
it does not work on linux.
See http://d.puremagic.com/issues/show_bug.cgi?id=1141
« First   ‹ Prev
1 2 3