On 6/18/10, bearophile <bearophileh...@lycos.com> wrote: > As I have said, you have to use operator overloading of the struct and some > near-ugly code that uses the offsetof. I don't like this a lot.
D need be no uglier than C. Here's my implementation: /* @very_unsafe */ struct TailArray(T) { T opIndex(size_t idx) { T* tmp = cast(T*) (&this) + idx; return *tmp; } T opIndexAssign(T value, size_t idx) { T* tmp = cast(T*) (&this) + idx; *tmp = value; return value; } } // And this demonstrates how to use it: import std.contracts; import std.c.stdlib; struct MyString { size_t size; TailArray!(char) data; // same as char data[0]; in C // to show how to construct it static MyString* make(size_t size) { MyString* item = cast(MyString*) malloc(MyString.sizeof + size); enforce(item !is null); item.size = size; return item; } static void destroy(MyString* s) { free(s); } } import std.stdio; void main() { MyString* str = MyString.make(5); scope(exit) MyString.destroy(str); // assigning works same as C str.data[0] = 'H'; str.data[1] = 'e'; str.data[2] = 'l'; str.data[3] = 'l'; str.data[4] = 'o'; // And so does getting for(int a = 0; a < str.size; a++) writef("%s", str.data[a]); writefln(""); }