Oh, I love pointers, but they don't love me!
ErNa
Posts: 1,752
Hello,
I'm still confused about the use of the @@ operator.
I start a process and pass a pointer to a field of pointers:
This data statement allows me to place the Parameters somewhere.
The first parameter tells the start procedure the number of entries in the array:
Because there is an different between compile and runtime addresses, I do a manual address correction, a method, which works but is not nice:
The start routine works like follows:
This procedure does the job but I have the strong feeling, it is not elegant. I should be able to correct the offset with the @@-Operator, but didn't find out, how. Any hint or help is appreciated.
ErNa
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
Post Edited (ErNa) : 8/1/2009 9:35:18 AM GMT
I'm still confused about the use of the @@ operator.
I start a process and pass a pointer to a field of pointers:
CON NmbrOfParameters = 5 ' Number of parameters passed to the started process via an array of pointerss Dat ProcParameters long @Parameter1, @Parameter2, @Parameter3, @Parameter5, @ Parameter5
This data statement allows me to place the Parameters somewhere.
The first parameter tells the start procedure the number of entries in the array:
Parameter1 := NmbrOfParametersAnzScre ' Tell the startroutine the number of valid addresses
Because there is an different between compile and runtime addresses, I do a manual address correction, a method, which works but is not nice:
repeat i from 0 to NmbrOfParameters -1 ' Manually add fix offset ProcParameters[noparse][[/noparse] i] += 16 i := Process.start(@ProcParameters) -1 ' starting process
The start routine works like follows:
PUB Start( PointerToArray ) | i Stop ' Store a local pointer to the variables passed to process via pointer array repeat i from 0 to LONG[noparse][[/noparse]LONG[noparse][[/noparse]GlobPtr + 0]]-1 ' First element is the NmbrOfParameters LONG[noparse][[/noparse]@LoclPtr + (i<<2)] := LONG[noparse][[/noparse]GlobPtr + (i<<2)] ' Adresses are stored to an local array ifnot ID_cog ID_cog := cognew(CogProz, @Sk) + 1 Long[noparse][[/noparse]CommandPtr] := 0 ' Show that process is up and running bei resetting NmbrOfParameters to zero Result := ID_Cog
This procedure does the job but I have the strong feeling, it is not elegant. I should be able to correct the offset with the @@-Operator, but didn't find out, how. Any hint or help is appreciated.
ErNa
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
Post Edited (ErNa) : 8/1/2009 9:35:18 AM GMT
Comments
Anyway, the manual fixup you're doing, adding 16, is what @@ does, except @@ adds the correct offset for the object it's in (it's not always 16).
you were right, this happens if you copy and paste. ProcParameters is the pointer to the process control block of the started process.
I tried to move the initialisation of the pointers (add the offset) into the called routine where I already have the loop to copy them to the local storage.
I thought that would be possible, but didn't find an elegant way.
when I change the code to:
it works. This is better for 16 as an fixed offset is just quick and dirty.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
The offset being 16 and I'm just adding an offset, I moved this to the called start routine. Now I have:
Now I manually add the offset but I was not able to do this with @@, but couldn't analyze, what @@ does now, because I have no debugging tool in this environment
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
There are two occasions you would use a pointer:
1-····· At run time
2-····· At compile time
During run time when you use a pointer to a variable whether it is in a Var section or a Dat section you will get the right address all the time. There is no need to use @@ to correct it.
At compile time referencing the address of a variable is resolved in relation to the start of the object. So when an @ is resolved at compile time it refers to the RELATIVE address of the variable to the start of the object.
At run time the object may not fit where the compiler assumed it did and thus the ACTUAL address of the variable will not be the same as the address calculated at compile time. So the @@ operator is used to resolve the actual address of the variable according to the already stored relative address.
The @@ operator is then only of use when you have a need to use @ at compile time and you need to correct it at run time.
This mostly occurs if you use the @ to store the address of a variable in a location within the DAT section which gets resolved at compile time and thus you will need to correct it later at run time.
This is usually necessary if you need to store a LIST of variable or memory locations that are not easily calculated from a BASE address at run time.
·
Consider these two programs
In your program (from what I can discern)· you do not need the first example since your variables are numerical and thus you know their lengths and can just use the method of the second example above.
I think you need to rethink the way you are doing your code.
Nevertheless, if you do need to do it the way you are doing it then now you know how the @@ operator works and what it does.
·
Samuel
So if I have a
DAT
VariablePtr Long @Variable1
and access to that Variable1 Value := @@VariablePtr
this will work (at least I hope)
but if I change VariablePtr at runtime to @Variable2
I gain access to Variable2 with Value := @VariablePtr
So, if I initialize a pointer via DAT, I have to update this pointer when the program starts and after that I can use this pointer in a "normal" way.
This piece of code is running as expected. LONG[noparse][[/noparse]GlobPtr] gives me the content of address GlobPtr and this content is again a pointer initialized via DAT. Now I expect @@LONG[noparse][[/noparse]GlobPtr] to add the offset, that is, 16. But that doesn't work. So, where is the mistake?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
Post Edited (ErNa) : 8/2/2009 3:43:57 PM GMT
What is LoclPtr? Why is there an AddrOffse and an AddrOffs?
this will work value := Long[noparse][[/noparse]@@variableptr]
@@variableptr will give you an adjusted address, not the value.
I think your confusion comes from C++. @@ is not a pointer to pointer nor is it a dereferencing of the pointer.
All @@ does is do automatically what you were doing manually by adding 16. But the system does it correctly in case
more or less than 16 is needed.....you determined 16 by looking at the difference in pointers no??? the system guarantees
that the correct value (could be 16 or less or more) is used to adjust the address when you use @@......but it is still an address.
In C++ we use * to indicate a pointer type, we use & to reference the address and we use * to dereference the address.
In Spin @ is to reference the address and Long[noparse]/noparse or Byte[noparse]/noparse or Word[noparse]/noparse is used to dereference the address. Also in Spin
you do not need to specifically declare a pointer variable as such, it is just another LONG variable.
So do not confuse @@ with **. It has no relation to C++ except in @ being a pointer referencing operator. @@ is a
pointer adjuster operator that adds (or subtracts) a certain·offset to the already stored address value.
If you change the VariablePtr at run time to @Variable2 you still can access the value using Long[noparse][[/noparse]@@variableptr].
but why......you can just say value:= Variable2.................
This is what I am talking about when I said that you need to rethink your code......I think you are overcomplicating the
program more than you need to................
If all you want is to have an array (list) of variables (longs, words or bytes)·and you are interested in accessing them
in a loop then you do it in either of two ways:
1- using an array
··· Var
······· Long myvalues[noparse][[/noparse]20]
···
··· Pub Main|i,x
······· repeat i from 0 to 19
············ x:= myvalues[noparse][[/noparse]i]
2- by using the address of a starting variable in the list
··· Var
······ Long v1, v2, v3··· 'you can use bytes or words
··· Pub Main|i,x
······· repeat i from 0 to 2
··········· x := Long[noparse][[/noparse]@v1][noparse][[/noparse]i]·· 'use word or byte if your variables are words or bytes
··········· 'or you can do it this way knowing that longs are 4 bytes
··········· x := Long[noparse][[/noparse]@v1+i*4]·· 'if your variables are bytes use 1 not 4 and if words then use 2 not 4
··········· 'or you can use << 2 to multiply by 4· <<1 to multiply by 2 (for words) and no shifting for bytes
··········· x := Long[noparse][[/noparse]@v1+i<<2]
As you can see there is no need to reference the variables in a·DAT section since their addresses can be
determined at run time with a simple formula.
The only time you need to reference the addresses in a DAT section is if there is·a need to access the variables
in a sequence and they are not contiguous and are of varying length such as there is no easy way to calculate
the addresses of each using a formula.
I think you are overcomplicating your program.
Samuel
···
Post Edited (SamMishal) : 8/2/2009 11:45:15 PM GMT
I run different processes in different cogs and these processes communicate.
The communication take place via LONG[noparse][[/noparse]Address].
It was often discussed, how variables are passed to processes, but I'm looking for a more general approach and it works, so far.
I start a new cog and pass a pointer to an array of pointers, initialized in a DAT section.
The problem is: the DAT- initialization at compile time creates pointers without offset.
Starting the program, I firstly change the pointers in the array with the @@ instruction in a loop one by one. That works.
But I now wanted to transfer this to the called initialisation routine.
Again the pointers are adjusted by adding 16. It works.
But when I try to adjust the pointers with @@, (in the called start method), it doesn't
Again the code:
This allows me to simply pass as many addresses as necessary to the cog-process. And there is no limitation where these addresses point to and what the references types are.
The pointers could be word because the memory is limited, but I don't care for that because the methods work both for spin and assembler.
At that moment all the pointers in the array "ProzScre" are compile time initialized.
The start method:
The repeat instruction now creates a local copy of the pointers and adds the offset to have the right runtime addresses.
LONG[noparse][[/noparse]LONG[noparse][[/noparse]GlobPtr + 0]+AddrOffs] reads the number of pointers to copy.
LONG[noparse][[/noparse]GlobPtr + 0]+AddrOffs is the address of that number. The " + 0" is just to indicate, that it is the first element of an array.
I expected that @@LONG[noparse][[/noparse]GlobPtr + 0] would do the same job. But it doesn't and I didn't have the time to analyze the difference.
The reason might be, that the called method has a different offset and that the @@ operator only works correctly in routine where the variables are defined.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away
Change
i := Scre.start(@ProzScre) -1
to
i := Scre.start(@ProzScre, @@0) -1
and in Scre:
PUB Start( GlobPtr, AddrOffs ) | i
(and delete CON AddrOffs = 16)
Another idea is to use an initialization method from within the object that contains the Dat section to adjust all the pointers before you
call the start of the cog residing object and passing it the address of the pointers list. This will adjust the actual values of the pointers in
the list before you use them in another object and thus you would not need to use the @@ at all from within the other object.
You would just use the address value that they now contain which will be the right address since you have adjusted them
using @@ from within the same object and all you would need is to derefrence it using Long[noparse]/noparse]Long[noparse][[/noparse]GlobalPtr][noparse][[/noparse]i.
Samuel
·
@Sam: initialization at start is possible and that is, what I did before. But I didn't like it for any reason. It's just stupid work ;.)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away