Obtaining aligned addresses and aligned spaces for objects

Ali Çehreli acehreli at yahoo.com
Tue Jun 28 22:42:37 PDT 2011


The address that is passed to emplace() must be properly aligned for that 
type. Am I correct in thinking that the following functions are a must? 
If so, do you think that they are correct? If so, are there equivalents 
in Phobos?

/**
 * Return an aligned address for the type at or after the
 * candidate address.
 */
T * alignedAddress(T)(T * candidate)
{
    return cast(T*)((cast(size_t)candidate + T.alignof - 1)
                    / T.alignof * T.alignof);
}

/**
 * A convenient overload for void*
 */
void * alignedAddress(T)(void * candidate)
{
    return alignedAddress(cast(T*)candidate);
}

/**
 * Return the size of the space that the type occupies from
 * one aligned address to the next.
 */
size_t alignedSpace(T)()
{
    static if (is (T == class)) {
        size_t size = __traits(classInstanceSize, T);
    } else {
        size_t size = T.sizeof;
    }

    return cast(size_t)alignedAddress(cast(T*)size);
}

Here is the rest of the program that uses those:

import std.stdio;
import core.memory;
import std.conv;

struct S
{
    string s;

    string toString()
    {
        return s;
    }
}

void main()
{
    /* Inputs to use to make objects */
    string[] inputs = [ "hello", "world" ];

    /* Raw memory */
    S * chunk = cast(S*)GC.calloc(inputs.length * alignedSpace!S());

    /* Make objects */
    foreach (i, str; inputs) {
        S * objectAddress = alignedAddress(chunk + i);
        emplace(objectAddress, str);
    }

    /* Convert from pointer to slice. Nice feature! :) */
    S[] objects = chunk[0 .. inputs.length];

    /* Use the objects */
    writeln(objects);
}

The output:

[hello, world]

On a related note, why doesn't __traits(classInstanceSize, T) consider 
the padding bytes? If I'm not mistaken struct sizes do include the 
padding bytes. The following class has the very odd size of 17! Is that 
by design?

class C
{
    char c;
}

void main()
{
    assert(__traits(classInstanceSize, C) == 17);
}

Ali


More information about the Digitalmars-d-learn mailing list