'Pre' vs Post-increment question.
lardom
Posts: 1,659
in Propeller 1
I assumed the difference between pre-increment and post-increment was not a big deal.
The following code increments 0 to 3
The following code increments 0 to 3
PUB Load_Packets(a) | idx load_up[idx] := a idx := ++idx//4 if idx == 3 TransmitStringThis code returns only zero. Why?
PUB Load_Packets(a) | idx load_up[idx] := a idx := idx++//4 if idx == 3 TransmitString
Comments
In the case of the first equation it gets written sequentially (in-order) and therefore acts as expected, but in the second equation gets written concurrently (out-of-order) with the second write being the one that counts. The second write will come from the modulus operation which will always have zero as its input in-turn because it always wrote zero as the second writer.
If the equation result didn't go back to idx then you wouldn't have a problem.
Pre-increment is fine because the increment happens first, THEN the usage in the expression. It actually turns into something like this:
In the second case, the code is probably computing the post-incremented version of idx "off to the side", like this:
You're essentially causing an order-of-operations snafu in the expression evaluator by telling it to assign a value AND increment a value after the expression.
As Jason points out, you can easily create conflicts with these operators so I do the idx adjustment after its required use.
There is a problem with snippet:
The variable idx is local hence temporary -- you need a global variable (that maintains its value) for this code to work the way you want. I would re-structure like this.
My guess is that idx is the length of the packet; after four values you want to transmit -- this seems a bit for obvious to me.
I will make the change. 'Avoid division when possible.' Execution speed does matter in this phase of my project.
BTW, I'd like to understand some of the ways a 4-byte-string differs from 4 byte variables that I can put in a parameter list. I want to control 4 servos wirelessly. If I transmit a byte string from DAT the Parallax Serial Terminal interprets it properly.
I can avoid a parameter list if I use cognew and pass a variable address to a child object but I can't figure out how to do the same wirelessly. I don't want anyone to have to wade too deep into the weeds for my project but I am puzzled.
So:
X // 2 is the same as X & 1
X // 8 is the same as X & 7
X // 256 is the same as X & 255
Beware that this only holds true for positive numbers though - The remainder of a division for negative numbers will be negative, whereas using the & trick will always give a positive result. That can be a useful side effect though - In JonnyMac's case, his roll over / roll under cases would both be handled by the same instruction: