Class Instance allocations

Justin Johansson no at spam.com
Wed Jan 13 07:29:35 PST 2010


I understand your quandary.

For me "Win32" == "32 bits" == "4 bytes" == "sizeof(ubiquitous machine 
register)".

So why on earth, since Visual Studio 2001 (and before?), was the default 
alignment set to 8 bytes for the M$ C/C++ compiler code generation 
option?  This I just do not understand (so, of course, enlightenment is 
welcome).

Beers for the New Years,

Justin Johansson



bearophile wrote:
> This page says "The pointer returned from new() must be to memory aligned to the default alignment. This is 8 on win32 systems.":
> http://www.digitalmars.com/d/2.0/memory.html
> 
> Is that true? Is this required by the tag bits added by the GC scans? Does std.c.stdlib.malloc always return aligned to 8 on Windows?
> 
> Below in the same page, in the Mark/Release section:
> 
> class Foo {
> ...
>     new(size_t sz)
>     {   void *p;
> 	p = &buffer[bufindex];
> 	bufindex += sz;
> 	if (bufindex > buffer.length)
> 	    throw new OutOfMemory;
> 	return p;
>     }
> ...
> 
> If sz is not a multiple of 8 then new() can return a pointer not aligned to 8:
> 
> import std.outofmemory: OutOfMemoryException;
> import std.gc: addRange, removeRange;
> import std.c.stdlib: malloc, free;
> import std.c.stdio: printf;
> 
> class Foo {
>     static void[] buffer;
>     static int bufIndex;
>     static const int bufSize = 100;
>     int x; //**********
> 
>     static this() {
>         void* p = malloc(bufSize);
>         if (!p)
>             throw new OutOfMemoryException;
>         addRange(p, p + bufSize);
>         buffer = p[0 .. bufSize];
>     }
> 
>     static ~this() {
>         if (buffer.length) {
>             removeRange(buffer.ptr);
>             free(buffer.ptr);
>             buffer = null;
>         }
>     }
> 
>     new(size_t sz) {
>         void* p = &buffer[bufIndex];
>         bufIndex += sz;
>         if (bufIndex > buffer.length)
>             throw new OutOfMemoryException;
>         printf("%d %d\n", cast(size_t)p, cast(size_t)p % 8); // ******
>         return p;
>     }
> 
>     delete(void* p) {
>         assert(0);
>     }
> 
>     static int mark() {
>         return bufIndex;
>     }
> 
>     static void release(int i) {
>         bufIndex = i;
>     }
> }
> 
> void main() {
>     int m = Foo.mark();
>     Foo f1 = new Foo;  // allocate
>     Foo f2 = new Foo;  // allocate
>     Foo.release(m);    // deallocate f1 and f2
> }
> 
> Output, f2 reference is now always aligned to 4 bytes:
> 1382368 0
> 1382380 4
> 
> So, does the new() in this class (that has that extra "x" field) need to be fixed to be sure the pointers it returns are aligned to 8?
> 
> The Foo class in the Mark/Release section has some other little bugs, that I think I have fixed here. D docs need something like the Andrei's book machinery, where D code snippets are actually run (Python docs too run their snippets).
> 
> Bye,
> bearophile



More information about the Digitalmars-d mailing list