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