Reputation: 2233
I have a very strange problem. Here is my code:
<declare E,JV>
<perform some actions with E>
JV.Math_Mul(E);
////
public new void Math_Mul(Matrix a)
{
double[,] vC = new double[a.ColCount, this.RowCount];
externExtensions.MatMul(vC,a.Values ,this.Values, a.RowCount, this.ColCount, a.ColCount);
Values = vC;
CopyB(B.Values,vC);
}
static unsafe void CopyB(double[,] B, double[,] val)
{
int Col = val.GetLength(1);
int j = 0;
fixed (double* pA = B, pB = val)
{
for (int i = 0; i < val.Length; i++)
{
if (i != j * Col)
pA[i-j] = pB[i];
else
j++;
}
}
}
After executing CopyB function something happens to E(which is very strange because it's not a parameter of CopyB) and VS 2012 tells me:Cannot obtain value of local or argument 'E' as it is not available at this instruction pointer, possibly because it has been optimized away. Code Optimization is turned off and this code worked well until i've made CopyB. So, what is the problem? What happens to E and what should i do?
PS CopyB is implemented for faster parse of matrix after multiplication, this is part of my mathematical tools, i work with block matrixes.
I'll be very grateful for any help!
Upvotes: 0
Views: 200
Reputation: 660159
Let's simplify your question:
I am looking at this code in the debugger.
static void Foo(int a, int b)
{
DoSomething(a);
DoSomethingElse(b);
}
Sometimes when attempting to look at
a
in the debugger afterDoSomething
has run I get the message "Cannot obtain value of local or argument 'a' as it is not available at this instruction pointer, possibly because it has been optimized away." What does this mean?
A formal parameter is a variable and that means that it must be implemented as a storage location. Since a formal parameter is of short lifetime, that storage location can be allocated on the short term pool. And that means that the jitter will either make it a stack location or a register.
Let's suppose it is a register. Registers are a scarce resource in x86 land, and so the jitter might want to use that register for something else in DoSomethingElse
. It knows it can do so safely because it knows that nothing after DoSomethingElse
refers to a
; a
is now "dead" as far as the jitter is concerned, so its register can be used for something else.
The debugger knows that the register no longer means a
so it will not allow you to be fooled into thinking that the value of the register is the value of a
. That value is gone because its storage is now being used for something else.
So this explains why the behaviour of the debugger changed when I added a new method call?
Yes. In your original program the jitter did not need to re-use the register, and so it had its original value throughout the method call.
Your actual scenario is just a more complicated version of this scenario with three methods involved. The jitter is likely re-using the register that represents your variable E
for something else.
Upvotes: 5