Size of a class instance at compile time

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Sat Jan 13 11:52:13 PST 2007


Daniel Keep wrote:
> 
> Ok, ASSUMING:
> 
> 1. I'm only going to be compiling with dmd...
> 2. ...for x86...
> 3. ...under Windows,

(2) is a bit redundant after (1)...
Also, AFAIK (3) doesn't matter in this respect.

> is this an accurate way of getting the size of a class instance at 
> compile time?
> 
>  > template InstanceSize(T)
>  > {
>  >     const uint InstanceSize = 12 + CountSizes!(typeof(T.tupleof));
>  > }
>  >
>  > template CountSizes()
>  > {
>  >     const uint CountSizes = 0;
>  > }
>  >
>  > template CountSizes(T)
>  > {
>  >     const uint CountSizes = T.sizeof;
>  > }
>  >
>  > template CountSizes(T, Tail...)
>  > {
>  >     const uint CountSizes = T.sizeof + CountSizes!(Tail);
>  > }

Sorry, it's not.

> It seems to report the right sizes, but I'm not entirely sure what the 
> '12' is for.  Pointer to ClassInfo, ... what else?

There are only 8 bytes of overhead: pointer to vtable and pointer to 
monitor. (the vtable contains the classinfo pointer)
See http://www.digitalmars.com/d/abi.html, under "Classes". It doesn't 
specifically mention how non-static members are formatted, but I think I 
figured it out (see below).

You also forgot to take alignment gaps into account.

Try this:
-----
template InstanceSize(T)
{
     const InstanceSize = CountSizes!(8, typeof(T.tupleof));
}

template CountSizes(size_t N)
{
     const CountSizes = N;
}

template CountSizes(size_t N, T)
{
     const uint CountSizes = AlignUp!(T.alignof, N) + T.sizeof;
}

template CountSizes(size_t N, T, Tail...)
{
     const uint CountSizes =
         CountSizes!(AlignUp!(T.alignof, N) + T.sizeof, Tail);
}


template AlignUp(size_t Align, size_t N) {
     static assert((Align & (Align - 1)) == 0,
                     "Alignment not power of two");
     const AlignUp = (N + Align - 1) & ~(Align - 1);
}


//
// Test code
//

class Test {	/// Change members to test different layouts
     char c;
     int i;
     byte b;
}

import std.stdio;

void main() {
     writefln("Static size: ", InstanceSize!(Test));
     writefln("Actual size: ", Test.classinfo.init.length);
}
-----


More information about the Digitalmars-d-learn mailing list