November 07, 2012 Struct-nested structs | ||||
|---|---|---|---|---|
| ||||
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:
```d
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.
| ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply