www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Sizeof class instance

reply Justin Johansson <no spam.com> writes:
How does one determine the sizeof (in bytes) of an instance of a class in D?

.sizeof works as advertised for structs, but for reference types,
.sizeof yields the sizeof the referencing variable (effectively same as size of
a pointer)
and not the size of the underlying instance.

I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

btw. I was poking under the hood of std.xml and though, wow, instances of
Element
class look humongous, and so I'm interested to how exactly how humongous.

Thanks for all help.
Justin
Oct 03 2009
next sibling parent Jeremie Pelletier <jeremiep gmail.com> writes:
Justin Johansson wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?
 
 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.
 
 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.
 
 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
 
 Thanks for all help.
 Justin
 
The only way I know of is to access the init array of the classinfo at runtime and get its length property.
Oct 03 2009
prev sibling next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in=
D?
 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as s=
ize of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf. =A0Perhaps I missed it=
in the latter.
 btw. I was poking under the hood of std.xml and though, wow, instances of=
Element
 class look humongous, and so I'm interested to how exactly how humongous.

 Thanks for all help.
 Justin
There's no way to get it at compile-time in D1. The best you can do is Class.classinfo.init.length. In D2, you can use __traits(classInstanceSize, Class).
Oct 03 2009
next sibling parent reply Justin Johansson <no spam.com> writes:
Jarrett Billingsley Wrote:

 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
 There's no way to get it at compile-time in D1. The best you can do is
 Class.classinfo.init.length.
 
 In D2, you can use __traits(classInstanceSize, Class).
Thanks Jeremie and Jarrett for answers. For investigative purposes (rather than adding up class member sizes in my head), would I get a fair answer if I copied the class data members into a struct, did a struct sizeof and added 4 bytes to allow for a virtual function table pointer (in the class and assuming the class has a VFT)?
Oct 03 2009
parent reply Jeremie Pelletier <jeremiep gmail.com> writes:
Justin Johansson wrote:
 Jarrett Billingsley Wrote:
 
 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
 There's no way to get it at compile-time in D1. The best you can do is
 Class.classinfo.init.length.

 In D2, you can use __traits(classInstanceSize, Class).
Thanks Jeremie and Jarrett for answers. For investigative purposes (rather than adding up class member sizes in my head), would I get a fair answer if I copied the class data members into a struct, did a struct sizeof and added 4 bytes to allow for a virtual function table pointer (in the class and assuming the class has a VFT)?
You forgot the monitor pointer of the class, so thats (size_t.sizeof * 2) to add to the size of the struct. I wasn't aware of the traits method either, I just made this helper template to simplify its syntax: template SizeOf(alias C) if(is(C == class)) { enum ClassSizeof = __traits(classInstanceSize, C); }
Oct 03 2009
next sibling parent Justin Johansson <no spam.com> writes:
Jeremie Pelletier Wrote:

 Justin Johansson wrote:
 Jarrett Billingsley Wrote:
 
 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
 There's no way to get it at compile-time in D1. The best you can do is
 Class.classinfo.init.length.

 In D2, you can use __traits(classInstanceSize, Class).
Thanks Jeremie and Jarrett for answers. For investigative purposes (rather than adding up class member sizes in my head), would I get a fair answer if I copied the class data members into a struct, did a struct sizeof and added 4 bytes to allow for a virtual function table pointer (in the class and assuming the class has a VFT)?
You forgot the monitor pointer of the class, so thats (size_t.sizeof * 2) to add to the size of the struct. I wasn't aware of the traits method either, I just made this helper template to simplify its syntax: template SizeOf(alias C) if(is(C == class)) { enum ClassSizeof = __traits(classInstanceSize, C); }
Sorry I misread the earlier answer. This works for my investigative purposes as explained: writefln( "Element instance size = %d", Element.classinfo.init.length); Still glad I asked this last question though because I hadn't thought of monitor. Also I imagine that if a class has interfaces, this can impact upon the size as well. My early years with microprocessors (8085, 8086, 6809 etc) and assembly language has always made me curious about how compilers realize their magic at the bit and byte level.
Oct 03 2009
prev sibling parent reply Justin Johansson <no spam.com> writes:
Jeremie Pelletier Wrote:

 Justin Johansson wrote:
 Jarrett Billingsley Wrote:
 
 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
 There's no way to get it at compile-time in D1. The best you can do is
 Class.classinfo.init.length.

 In D2, you can use __traits(classInstanceSize, Class).
Thanks Jeremie and Jarrett for answers. For investigative purposes (rather than adding up class member sizes in my head), would I get a fair answer if I copied the class data members into a struct, did a struct sizeof and added 4 bytes to allow for a virtual function table pointer (in the class and assuming the class has a VFT)?
You forgot the monitor pointer of the class, so thats (size_t.sizeof * 2) to add to the size of the struct. I wasn't aware of the traits method either, I just made this helper template to simplify its syntax: template SizeOf(alias C) if(is(C == class)) { enum ClassSizeof = __traits(classInstanceSize, C); }
Okay so PODO alone is 8 bytes. writefln( "Object: %d", Object.classinfo.init.length); Object: 8 And we're talking 9 bytes for a simple boxed bool and 12 bytes for a simple boxed 32-bit integer by the looks of things. class Foo { bool value; } class Bar { int value; } writefln( "Foo: %d", Foo.classinfo.init.length); writefln( "Bar: %d", Bar.classinfo.init.length); Foo: 9 Bar: 12 On top of that there is possibly alignment in the heap so my 9 byte Foo would occupy 12 or 16 bytes of address space. Would that be correct? Thanks for answers. Justin.
Oct 04 2009
parent Jeremie Pelletier <jeremiep gmail.com> writes:
Justin Johansson wrote:
 Jeremie Pelletier Wrote:
 
 Justin Johansson wrote:
 Jarrett Billingsley Wrote:

 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
There's no way to get it at compile-time in D1. The best you can do is Class.classinfo.init.length. In D2, you can use __traits(classInstanceSize, Class).
Thanks Jeremie and Jarrett for answers. For investigative purposes (rather than adding up class member sizes in my head), would I get a fair answer if I copied the class data members into a struct, did a struct sizeof and added 4 bytes to allow for a virtual function table pointer (in the class and assuming the class has a VFT)?
You forgot the monitor pointer of the class, so thats (size_t.sizeof * 2) to add to the size of the struct. I wasn't aware of the traits method either, I just made this helper template to simplify its syntax: template SizeOf(alias C) if(is(C == class)) { enum ClassSizeof = __traits(classInstanceSize, C); }
Okay so PODO alone is 8 bytes. writefln( "Object: %d", Object.classinfo.init.length); Object: 8 And we're talking 9 bytes for a simple boxed bool and 12 bytes for a simple boxed 32-bit integer by the looks of things. class Foo { bool value; } class Bar { int value; } writefln( "Foo: %d", Foo.classinfo.init.length); writefln( "Bar: %d", Bar.classinfo.init.length); Foo: 9 Bar: 12 On top of that there is possibly alignment in the heap so my 9 byte Foo would occupy 12 or 16 bytes of address space. Would that be correct? Thanks for answers. Justin.
The GC allocates memory in blocks using sizes which are powers of 2, starting at 16 bytes and going up to 4096 bytes, this alignment is used for various optimizations. Objects should be used for their inheritance features, if you don't need inheritance you should stick to POD structs, although they require a different handling since they're value types (vs objects which are reference types) and don't always get allocated on the heap.
Oct 04 2009
prev sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson <no spam.com> wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.

 Thanks for all help.
 Justin
There's no way to get it at compile-time in D1. The best you can do is Class.classinfo.init.length.
What nonsense, of course there is! http://gist.github.com/140531 Note: this is VERY old code, but I have no reason to think it won't still work. I may need a little dusting off...
Oct 03 2009
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Daniel Keep wrote:
 ...
 Note: this is VERY old code, but I have no reason to think it won't
 still work.  I may need a little dusting off...
*It* may need a little dusting off. Argh.
Oct 03 2009
prev sibling parent reply grauzone <none example.net> writes:
Justin Johansson wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?
 
 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.
As Jarrett said, x.classinfo.init.length is the simplest way in D1.
 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.
I guess that PDF is horribly outdated, although it may work for some purposes.
 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
Wasn't std.xml for D2? Anyway, last what I remember is that std.xml is unmaintained, slow, buggy, and shouldn't be seriously used.
 Thanks for all help.
 Justin
 
Oct 04 2009
parent reply Justin Johansson <no spam.com> writes:
grauzone Wrote:

 Justin Johansson wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?
 
 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.
As Jarrett said, x.classinfo.init.length is the simplest way in D1.
 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.
I guess that PDF is horribly outdated, although it may work for some purposes.
 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
Wasn't std.xml for D2? Anyway, last what I remember is that std.xml is unmaintained, slow, buggy, and shouldn't be seriously used.
Yes and yes. I'm currently using D1 but with view to D2 am having a peek at it's libs. I can see why std.xml in D2 is slow, and would not be surprised if buggy as well; it is quite disgusting code that's been hacked together without any real rhyme or reason. So guess I'll be writing my own stuff and leveraging on C libs where possible. Got Expat parser running with D without too much trouble. Thanks for comment grauzone. -- Justin Johansson
Oct 04 2009
parent grauzone <none example.net> writes:
Justin Johansson wrote:
 grauzone Wrote:
 
 Justin Johansson wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size
of a pointer)
 and not the size of the underlying instance.
As Jarrett said, x.classinfo.init.length is the simplest way in D1.
 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the
latter.
I guess that PDF is horribly outdated, although it may work for some purposes.
 btw. I was poking under the hood of std.xml and though, wow, instances of
Element
 class look humongous, and so I'm interested to how exactly how humongous.
Wasn't std.xml for D2? Anyway, last what I remember is that std.xml is unmaintained, slow, buggy, and shouldn't be seriously used.
Yes and yes. I'm currently using D1 but with view to D2 am having a peek at it's libs. I can see why std.xml in D2 is slow, and would not be surprised if buggy as well; it is quite disgusting code that's been hacked together without any real rhyme or reason. So guess I'll be writing my own stuff and leveraging on C libs where possible. Got Expat parser running with D without too much trouble.
In case you didn't know, Tango's XML parser is said to be even faster than other commonly used XML parsers in C/Java: http://dotnot.org/blog/archives/2008/03/10/xml-benchmarks-updated-graphs-with-rapidxml/ Also: http://prowiki.org/wiki4d/wiki.cgi?AllLibraries/XmlLibraries
 Thanks for comment grauzone.
 
 -- Justin Johansson
  
Oct 04 2009