View mode: basic / threaded / horizontal-split · Log in · Help
December 09, 2012
struct in class access
Why can't a struct inside a class access the members of that 
class without a this pointer? It would seem natural to me that a 
nested struct should probably be special in that it is really 
just a special container to reduce clutter in the class.

class a {
   string v;
   struct b { void fun() { writeln(v); } }
   b bb;
}

should be semantically equivalent to

class a {
   string v;
   void bb.fun() { writeln(v); }
}

(and struct b does not have to include a "this" pointer since it 
is passed down)

I'm in need of using structs to wrap opAssign so I can override 
for each variable(instead of a special method for each field in 
the class, which adds clutter and prevents using `=` properly). 
But I also want to access the class container's members. (and 
without having to enlarge the struct)

It seems to me that the compiler should not have any difficult 
treating a struct method as a class method(passing the this ptr 
to it) but operating on struct's data.

What's the difference between

class a {
   int x;
}

and

class a {
   struct b { alias _x this; int _x; }
   b x;
}

? (and if be is made to be used inside the class only then it 
seems as if it's just basically no different than using the class 
alone except for some simplification(has it's own op's that one 
unfortunately can't keep distinct from the class align since they 
would overlap(although it would be nice).

e.g.,


class a {
   string Name;
   void opAssign(T q) { };      // classes opAssign

   //{{ Essentially a struct here
     int x;
     void opAssign_x(T q) { writeln(Name); };   // Somehow 
overrides = for x. ('structs' opAssign)
   //}}
}

and

class a {
   string Name;
   void opAssign(T q) { };
   struct b { alias _x this; int _x; void opAssign(T q) { 
writeln(Name); }; } // Unfortunately we can't access Name
   b x;
}

i.e., it would seem to me that the only difference in the method 
opAssign of the struct is the offsets of the member variables is 
different(one referenced to the start of the struct and the first 
references them to start of the class.

Therefor we shouldn't have any issues having properties from both 
the *true* nested struct and directly inlining it. i.e., we 
should be able to access outer members(the functionality when we 
inline the struct into the class) AND have multiple opAssign's(or 
any ops) per class that can be specified for any field(which is 
the functionality we get when we use the struct).

Essentially what it boils down to is that nested structs do 
contain a this pointer to the parent class, so why can't we use 
it? (it's just some offset difference between the struct and 
class)

I do realize that nested structs are not special in the current 
implementation AFAIK which to me, is a waste as they should be 
special. In any case, is there some other way to get the same 
behavior in D?

One might say why don't I use classes as it solves the problem 
directly BUT there is a ton of wasted overhead for simply 
wrapping values.

I would use template mixin's but the opAssigns would clash AFAIK. 
The struct encapsulation lets me get the correct opAssign 
behavior which is what I need but prevent me from accessing the 
outer class members which I should be able to do.
December 09, 2012
Re: struct in class access
On Sunday, December 09, 2012 07:54:25 js.mdnq wrote:
> Why can't a struct inside a class access the members of that
> class without a this pointer? It would seem natural to me that a
> nested struct should probably be special in that it is really
> just a special container to reduce clutter in the class.

Without a this pointer, there are no class members to access, because they 
have to be associated with a specific instance of the class unless they're 
static. Non-static, nested structs have access to their enclosing scope, but 
then you can't create them separate from the enclosing class. However, if you 
declare a nested class to be static, it has no access to the class' members 
and is not associated with a specific instance of the class. It's just that 
it's declared inside the class instead of outside of it.

- Jonathan M Davis
December 09, 2012
Re: struct in class access
On Sunday, 9 December 2012 at 07:24:57 UTC, Jonathan M Davis 
wrote:
> On Sunday, December 09, 2012 07:54:25 js.mdnq wrote:
>> Why can't a struct inside a class access the members of that
>> class without a this pointer? It would seem natural to me that 
>> a
>> nested struct should probably be special in that it is really
>> just a special container to reduce clutter in the class.
>
> Without a this pointer, there are no class members to access, 
> because they
> have to be associated with a specific instance of the class 
> unless they're
> static. Non-static, nested structs have access to their 
> enclosing scope, but
> then you can't create them separate from the enclosing class. 
> However, if you
> declare a nested class to be static, it has no access to the 
> class' members
> and is not associated with a specific instance of the class. 
> It's just that
> it's declared inside the class instead of outside of it.
>
> - Jonathan M Davis

NOOOOOOOOO!!!! It does have a this pointer!! If the sub-struct is 
a true sub struct then it is inline inside the memory of the 
class! That is, any member inside a struct can easily be gotten 
from the pointer to the class(object) as one just has to add a 
simple(and static) offset.

If the struct is only used inside the class then there should be 
no problem.

If you look at the two examples I gave between a class and a 
struct inside a class, there is NO difference except for syntax! 
(excluding the way D does it already).

I'm not trying to define how D does it, but how D should do 
it(assuming there is no blatant logic errors that makes it 
impossible).

It makes no sense to have a struct inside a class behave exactly 
as that outside as it offers no benefit to do so(or maybe it 
does, but very little). Hence, we can redefine the way structs 
behave inside classes to make them more useful.

In fact, maybe a struct is not the best way to do this but it 
requires very little modification.

In any case, take this example:

class A {
public:
    string Name;
    struct B { public: int x; alias x this; void func(A _a) { 
writeln(_a.Name, x, y); }}
    B x;
    B y;
}

...

A a;

What is the address of A?

What is the address of x inside A? (i.e., the struct inside A?)

Is it not a simple static offset from the address of A? i.e., 
knowing the address of a lets us know the address of x. Knowing 
the address of x also lets us know the address of a! (Same goes 
for y)

This is why a nested struct(using my semantics) contains the this 
pointer! (because it is a simple offset from the this pointer 
which can be computed at compile time)!

NOW!! In this case, a nested struct is simply making an 
encapsulation of class data but effectively is equivalent to 
having the data inside the class. (but allows us to avoid 
collisions between overrides in the class and the struct, which 
is why I think it will be more useful to have such behavior than 
the current(since the current seems to offer nothing useful).



(
December 09, 2012
Re: struct in class access
>
> ...
>
> A a;
>
> What is the address of A?
>
> What is the address of x inside A? (i.e., the struct inside A?)
>

I of course, mean a, which is why it's nice to have the ability 
to make an edit so I don't have to waste a post and/or someone 
else bloat the thread with "A is a class, not an object, go learn 
how to program!".
December 09, 2012
Re: struct in class access
On Sunday, 9 December 2012 at 07:39:29 UTC, js.mdnq wrote:
> On Sunday, 9 December 2012 at 07:24:57 UTC, Jonathan M Davis 
> wrote:
>> On Sunday, December 09, 2012 07:54:25 js.mdnq wrote:
>>> Why can't a struct inside a class access the members of that
>>> class without a this pointer? It would seem natural to me 
>>> that a
>>> nested struct should probably be special in that it is really
>>> just a special container to reduce clutter in the class.
>>
>> Without a this pointer, there are no class members to access, 
>> because they
>> have to be associated with a specific instance of the class 
>> unless they're
>> static. Non-static, nested structs have access to their 
>> enclosing scope, but
>> then you can't create them separate from the enclosing class. 
>> However, if you
>> declare a nested class to be static, it has no access to the 
>> class' members
>> and is not associated with a specific instance of the class. 
>> It's just that
>> it's declared inside the class instead of outside of it.
>>
>> - Jonathan M Davis
>
> NOOOOOOOOO!!!! It does have a this pointer!! If the sub-struct 
> is a true sub struct then it is inline inside the memory of the 
> class! That is, any member inside a struct can easily be gotten 
> from the pointer to the class(object) as one just has to add a 
> simple(and static) offset.

That is why nested struct inside a class actually does not have a 
context pointer -its fields addresses are calculated as offsets 
from class this pointer, not from struct this pointer.

> If the struct is only used inside the class then there should 
> be no problem.

Problems comes when nested struct is created inside a function 
without creating a class.

> It makes no sense to have a struct inside a class behave 
> exactly as that outside as it offers no benefit to do so(or 
> maybe it does, but very little). Hence, we can redefine the way 
> structs behave inside classes to make them more useful.

Perhaps the situation can be improved.

> In any case, take this example:
>
> class A {
> public:
>     string Name;
>     struct B { public: int x; alias x this; void func(A _a) { 
> writeln(_a.Name, x, y); }}
>     B x;
>     B y;
> }
>
> ...
>
> A a;
>
> What is the address of A?

Meaning a, it is null.

> What is the address of x inside A? (i.e., the struct inside A?)

x does not exists

> Is it not a simple static offset from the address of A? i.e., 
> knowing the address of a lets us know the address of x. Knowing 
> the address of x also lets us know the address of a! (Same goes 
> for y)

Yes, it is a CT-known offset which varies from one class to 
another. Note, you can insert nested struct into another class.

> This is why a nested struct(using my semantics) contains the 
> this pointer! (because it is a simple offset from the this 
> pointer which can be computed at compile time)!

That's why nested struct does not have this pointer - it is POD 
structure.

http://dpaste.dzfl.pl/76e8ec0a
December 09, 2012
Re: struct in class access
On Sunday, 9 December 2012 at 06:54:33 UTC, js.mdnq wrote:
> Why can't a struct inside a class access the members of that 
> class without a this pointer? It would seem natural to me that 
> a nested struct should probably be special in that it is really 
> just a special container to reduce clutter in the class.

Your problem have obvious and simple workaround 
http://dpaste.dzfl.pl/701affe8
December 09, 2012
Re: struct in class access
On Sunday, 9 December 2012 at 08:56:00 UTC, Maxim Fomin wrote:
> On Sunday, 9 December 2012 at 07:39:29 UTC, js.mdnq wrote:
>> On Sunday, 9 December 2012 at 07:24:57 UTC, Jonathan M Davis 
>> wrote:
>>> On Sunday, December 09, 2012 07:54:25 js.mdnq wrote:
>>>> Why can't a struct inside a class access the members of that
>>>> class without a this pointer? It would seem natural to me 
>>>> that a
>>>> nested struct should probably be special in that it is really
>>>> just a special container to reduce clutter in the class.
>>>
>>> Without a this pointer, there are no class members to access, 
>>> because they
>>> have to be associated with a specific instance of the class 
>>> unless they're
>>> static. Non-static, nested structs have access to their 
>>> enclosing scope, but
>>> then you can't create them separate from the enclosing class. 
>>> However, if you
>>> declare a nested class to be static, it has no access to the 
>>> class' members
>>> and is not associated with a specific instance of the class. 
>>> It's just that
>>> it's declared inside the class instead of outside of it.
>>>
>>> - Jonathan M Davis
>>
>> NOOOOOOOOO!!!! It does have a this pointer!! If the sub-struct 
>> is a true sub struct then it is inline inside the memory of 
>> the class! That is, any member inside a struct can easily be 
>> gotten from the pointer to the class(object) as one just has 
>> to add a simple(and static) offset.
>
> That is why nested struct inside a class actually does not have 
> a context pointer -its fields addresses are calculated as 
> offsets from class this pointer, not from struct this pointer.
>
>> If the struct is only used inside the class then there should 
>> be no problem.
>
> Problems comes when nested struct is created inside a function 
> without creating a class.
>
>> It makes no sense to have a struct inside a class behave 
>> exactly as that outside as it offers no benefit to do so(or 
>> maybe it does, but very little). Hence, we can redefine the 
>> way structs behave inside classes to make them more useful.
>
> Perhaps the situation can be improved.
>
>> In any case, take this example:
>>
>> class A {
>> public:
>>    string Name;
>>    struct B { public: int x; alias x this; void func(A _a) { 
>> writeln(_a.Name, x, y); }}
>>    B x;
>>    B y;
>> }
>>
>> ...
>>
>> A a;
>>
>> What is the address of A?
>
> Meaning a, it is null.
>
>> What is the address of x inside A? (i.e., the struct inside A?)
>
> x does not exists
>
>> Is it not a simple static offset from the address of A? i.e., 
>> knowing the address of a lets us know the address of x. 
>> Knowing the address of x also lets us know the address of a! 
>> (Same goes for y)
>
> Yes, it is a CT-known offset which varies from one class to 
> another. Note, you can insert nested struct into another class.
>
>> This is why a nested struct(using my semantics) contains the 
>> this pointer! (because it is a simple offset from the this 
>> pointer which can be computed at compile time)!
>
> That's why nested struct does not have this pointer - it is POD 
> structure.
>
> http://dpaste.dzfl.pl/76e8ec0a

Yes, this is basically what I mean. structs to have addresses as 
everything does in memory. But structs are created "inline". I do 
not know what you mean x does not exist and the address of a. x 
does exist(in the sense of any other variable) and a does have an 
address.


You say

> That is why nested struct inside a class actually does not have 
> a context pointer -its fields addresses are calculated as 
> offsets from class this pointer, not from struct this pointer.

But if this is true, and a difference between nested structs, 
then there should be no issue implementing what I am talking 
about.

What I am talking about would require the struct to only be used 
inside the class as a class field. (as the struct is just 
encapsulating members of the class and not meant to stand on it's 
own, because, as you said, it would need a this pointer 
associated with it)

With my method, I should easily be able calculate, from a 
relative offset, the members of the class and use them. This 
means that the compiler should be able to do it for me. It then 
means that nested structs are not just structs stuck in a class 
for who knows what reason but actually signify that they are 
specially related to the class.

e.g.,

class A {
public:
	string Name;
	struct B {
		int x;
		void func(ref A tthis, int ofs)
		{
			byte *ptr = cast(byte*)tthis;
			ptr += ofs;
			writeln(*(cast(string*)(ptr)));		
		}

		this(int y) { x = y; }

	}
	B b;
	
	this() { Name = "test"; b = B(3); }
}


	A a = new A();
	a.b.func(a, 8);


prints "test" as expected.

B.func acts just like a member of A in that it takes a this 
pointer just like any other member of A. It could be moved 
outside of the struct into A.

Semantically there is little difference between using func inside 
B or inside A EXCEPT that we have to provide the static offsets 
and this ptr manually. If the compiler did it for us we would 
could then use the struct as a way to provide encapsulation for 
types inside the class so each could have it's own unique set of 
overloads(as they won't then conflict with the class overloads).

This is the whole point. Obviously, a nested struct inside a 
class has the ability to access it's class members(or, rather, 
it's parents members) simply by "moving" all it's methods into 
the class(but we see still think they are in the struct).

e.g., the above class has the exact same internal functionality 
as this:

class A {
public:
	string Name;
	struct B {
		int x;
		this(int y) { x = y; }
	}
	B b;
	void func()
	{
	        writeln(Name);		
	}
	
	this() { Name = "test"; b = B(3); }
}

(of course, we might have collisions now and we also have to call 
func through A instead of B but we get the benefit of not having 
to hard code the offset).
December 09, 2012
Re: struct in class access
On Sunday, 9 December 2012 at 09:06:28 UTC, Maxim Fomin wrote:
> On Sunday, 9 December 2012 at 06:54:33 UTC, js.mdnq wrote:
>> Why can't a struct inside a class access the members of that 
>> class without a this pointer? It would seem natural to me that 
>> a nested struct should probably be special in that it is 
>> really just a special container to reduce clutter in the class.
>
> Your problem have obvious and simple workaround 
> http://dpaste.dzfl.pl/701affe8


Nope, sorry, as I said, I do not want to keep 4 to 8 bytes FOR NO 
REASON! It doesn't have to be done that way and it is not a work 
around. It is simply a waste of space.
Top | Discussion index | About this forum | D home