Why no acess to other structs in classes?
Bill Baxter
dnewsgroup at billbaxter.com
Sun Nov 5 16:02:17 PST 2006
Bill Baxter wrote:
> BCS wrote:
>> Accessing the outer class would require a pointer to it. The only way
>> to get that
>> pointer would be to add a hidden value to the struct. In D, structs
>> are bare bones
>> aggregates without any hidden stuff added in.
>>
>> == Quote from Karen Lanrap (karen at digitaldaemon.com)'s article
>>> class C
>>> {
>>> struct S
>>> {
>>> uint data;
>>> }
>>> S s;
>>> struct T
>>> {
>>> uint f()
>>> {
>>> return s.data;
>>> // this for s needs to be type C not type T *
>>> }
>>> }
>>> }
>>> void main(){}
>>
>
> I don't think so. Structs are always treated like plain old data. So
> in memory this:
> class C
> {
> int a;
> int b;
> }
> has exactly the same layout as
> class C
> {
> int a;
> struct S { int b; }
> S s;
> }
>
> Therefore, if it is possible for S to compute the address to it's own
> members:
> class C
> {
> int a;
> struct S {
> int b;
> int f() { return b+1; }
> }
> S s;
> }
>
> Then it should also be possible for S to compute the address of members
> in the outer class at compile time.
>
> Try running this program:
> ------------
> import std.stdio : writefln;
>
> class C
> {
> int a;
> struct S {
> int b;
> int outer_a() {
> return cast(int)* (cast(char*)(&b)-int.sizeof);
> }
> }
> S s;
> }
>
> void main()
> {
> C c = new C;
> c.a = 42;
> writefln("c.a's value is ", c.s.outer_a());
> }
> ---------------
>
> The offset to the members of the outer class (or outer struct) are
> compile time constants. It's well within the compiler's ability to
> compute them.
>
> --bb
Ok ok. I was wrong. It is a little more complicated than that. If you
have two instances of S inside the class, then you'd need two instances
of the method outer_a, each with it's own compile time offsets. But
then something like
outer_a() {
static int num_calls++;
...
}
would fail.
One solution would be to add the hidden pointer-to-outer member to any
structs that use the "outer" property. If you don't use it, you don't
pay for it. Rather like how virtual functions are handled in C++. If
you don't declare any methods to be virtual, then the compiler doesn't
generate a vtable.
In the mean time, the obvious workaround is to give the structs a
pointer to the outer class yourself.
class C
{
int a;
this() {
s.outer = this;
s2.outer = this;
}
struct S {
int b;
int whats_A() {
this.b += 1;
return outer.a;
}
C outer;
}
S s;
S s2;
}
--bb
More information about the Digitalmars-d-learn
mailing list