So lets see what actually happens under the hood in IL.
Here I wrote up your example:
And we get this IL for your code where you use *=:
IL_0019: ldloc.0
IL_001a: ldloc.1
IL_001b: call valuetype SomeStruct SomeStruct::op_Multiply(valuetype SomeStruct, valuetype SomeStruct)
IL_0020: stloc.0
What this code is saying is:
load variable 0 onto stack (this would be 'a' in my code)
load variable 1 onto stack (this would be 'b' in my code)
call the static method SomeStruct.op_Multiply with signature that takes 2 SomeStruct's as parameters
pop value at top of stack into variable 0 (this would be a in my code)
Note that how methods are called in IL is that you push N number of values onto the memory stack that match the method signature, then call the method. This is how values are actually passed in memory to methods… via the stack this way. Same with returns… when you return a value really the IL pushes the return value onto the stack, and the calling code pops it off the stack into its place in memory.
Next, really the *= is just syntax sugar for a = a * b… and that’s really just syntax sugar for a = SomeStruct.op_Multiply(a,b). Which compiles into that IL.
Now when you say:
I will say…
The ‘value’ that is ‘someStructVariable’ will be what is in a. And the value that is ‘otherSomeStructVariable’ will be was in in b.
But I’m not sure what assumptions you’re making beyond that.
It’d be like if you said:
a = 3;
b = 5;
a *= b;
In the op_Multiply of that, the 1st parameter will be 3, and the 2nd will be 5.
But if you’re hoping some sort of ‘state’ will pass along… well no. Because a struct by design shouldn’t pass state (unless you use ‘ref’ or ‘out’).
But order wise… yes… the order is guaranteed to be preserved. Otherwise non-commutative operations (division, subtraction, quaternion multiplication) wouldn’t work. And since we know quat1 *= quat2 is guaranteed valid, we know it must respect order.