www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A devil self reference

reply Alex <sascha.orlov gmail.com> writes:
Hi all.
Finally, I arrived at something like this:

´´´
void main()
{
	S!(sarr)[] sarr;
}

struct S(alias Reference)
{
	size_t id()
	in
	{
		// not static assert, only because a pointer is never known in 
advance
		assert(Reference.ptr <= &this);
	}
	do
	{
		return &this - Reference.ptr;
	}
}
´´´

Of course, this does not compile, because I try to use an 
identifier before I defined it.

However, the reason I dare to ask is, that all the stuff with the 
weird self reference is compile time known.

So, is there a possibility to define something like the thing 
above?
Aug 15 2018
next sibling parent Alex <sascha.orlov gmail.com> writes:
On Wednesday, 15 August 2018 at 16:40:49 UTC, Alex wrote:
 Hi all.
 Finally, I arrived at something like this:

 ´´´
 void main()
 {
 	S!(sarr)[] sarr;
 }

 struct S(alias Reference)
 {
 	size_t id()
 	in
 	{
 		// not static assert, only because a pointer is never known 
 in advance
 		assert(Reference.ptr <= &this);
 	}
 	do
 	{
 		return &this - Reference.ptr;
 	}
 }
 ´´´

 Of course, this does not compile, because I try to use an 
 identifier before I defined it.

 However, the reason I dare to ask is, that all the stuff with 
 the weird self reference is compile time known.

 So, is there a possibility to define something like the thing 
 above?
containment in a container is also wanted... struct Container { S!(sarr)[] sarr; } but also not possible in this form because of a circular reference.
Aug 15 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, August 15, 2018 10:40:49 AM MDT Alex via Digitalmars-d-learn 
wrote:
 Hi all.
 Finally, I arrived at something like this:

 
 void main()
 {
   S!(sarr)[] sarr;
 }

 struct S(alias Reference)
 {
   size_t id()
   in
   {
       // not static assert, only because a pointer is never known in
 advance
       assert(Reference.ptr <= &this);
   }
   do
   {
       return &this - Reference.ptr;
   }
 }
 

 Of course, this does not compile, because I try to use an
 identifier before I defined it.

 However, the reason I dare to ask is, that all the stuff with the
 weird self reference is compile time known.

 So, is there a possibility to define something like the thing
 above?
What are you actually trying to do? Aside from the circular reference issues, using the address of a struct like that is very risky, because if the struct is ever moved, it will change. Also, even if the circular reference worked, the struct is then in a dynamic array on the heap, whereas the dynamic array itself is on the stack. So, you're trying to subtract a stack pointer from a heap pointer. - Jonathan M Davis
Aug 15 2018
parent Alex <sascha.orlov gmail.com> writes:
On Wednesday, 15 August 2018 at 21:42:11 UTC, Jonathan M Davis 
wrote:
 What are you actually trying to do? Aside from the circular 
 reference issues, using the address of a struct like that is 
 very risky, because if the struct is ever moved, it will change.
Yeah... my functions are all ref. Or work with slices...
 Also, even if the circular reference worked, the struct is then 
 in a dynamic array on the heap, whereas the dynamic array 
 itself is on the stack. So, you're trying to subtract a stack 
 pointer from a heap pointer.
Hm... didn't thought of that. Does this matter? My current form is like that: ´´´ void main() { S.c.sarr.length = 5; S.c.sarr[2 .. 4].usefulFun; } struct Container { S[] sarr; } struct S { static Container c; size_t id() { return &this - c.sarr.ptr; } void anotherUsefulFun() { /* works on "neighbors" of this, which are only available, if c.sarr is "well-known" */ } } void usefulFun(S[] slice) { import std.stdio; writeln(slice[0].id); } ´´´ It works. After a lot of debugging and head aches, it works as I want to. But, only until I try to copy the array, as you said. I'm aware of the problem, and I worked it out so far, that on copies of the array sarr only the operations are done, which do not need the pointer stuff. Like dumping the data, for example, or querying elementary properties. Even querying for id on a array copy is ok, if I do it with another function, let's call it indexOf :) What doesn't work are the calls to "neighbor"-acting functions, but these are not needed on sarr copies. The project is almost finished, so, I'm mainly after a learn effect now. What I'm looking for, is something what would simplify my structure. So... I can think at least of two things: 1. something, where I don't need the dangerous pointer stuff. 2. something, which works well after I copy it. If the circular stuff worked, it would simplify my life a lot. I could define some constructors, for copying data between arrays, whereas the pointer stuff would maintain itself, as it would be "integrated" into the type. But ok, I see, that this is at least kind of strange...
Aug 15 2018