November 07, 2012
I don't know whether it's ever planned that the following is supported, but every so often I see bearophile keep mentioning that it will be supported so I want to state my opinion on this:

struct A
    int bb;

    struct B
        void inc() { bb++; }
        byte b;

Is this really a feature in the making?

If this becomes supported it can cause subtle issues when interfacing with C. You could accidentally create a hidden field by accessing a field from an outer scope (accidents happen..), and you wouldn't know anything is wrong until you'd either get a crash, or corrupt data, or worse, data that is missing because it was written to a context field without you knowing.

For example maybe you're calling some external C function that fills your struct with whatever data but needs to know the size of the struct:

A.B struct;
cFunc(&struct, sizeof(A.B))

Whoops! You thought cFunc is going to write over the 1-byte field 'data', but it will actually write anywhere from 8-bytes to 16-bytes (based on whether x64 is in play) over the context pointer. So at first glance it will appear as though you're getting incomplete data from the C function.

But it's not just interfacing with C, you could have D code that relies on a struct being the size of its member fields. Sure you could use `static assert(typeof(this).sizeof == 1)`, but that relies on convention.

And if we're going to be forced to write `static struct` everywhere then we might as well say structs are not POD by default. I'm against this feature because we already have a definition that says structs are POD, and they're used immensely when interfacing with C. Having them *magically* insert a context pointer by a simple typo is way too dangerous.

Note that the OP sample had a typo, it increments 'bb' instead of 'b', so this would create a context pointer and make A.B either 8 or 12 bytes in size (1 byte for 'data' field, 4 or 8 bytes for the context pointer, and the rest is due to alignment).

With classes this is isn't a problem since you use special syntax in order to instantiate a nested class and this typo would never pass the compilation stage. But with structs having a defined .init property you could easily end up using a struct-nested struct which isn't a POD type even though you assumed it is. "static struct" comes to the rescue, but it relies solely on convention.
Top | Discussion index | About this forum | D home