I have found what seems to be an anomaly in VS2012 debugger display of managed arrays using C++/CLI. It seems when I try to use a simple math expression for the index the debugger displays element 0 instead. See watch window below.
The declaration of the array looks like this.
/* Stack where the values of tokens are stored */
array<YYSTYPE>^ yyv = gcnew array<YYSTYPE> (YYMAXDEPTH);
If elements are expanded it shows for certain that the yyv[4-1] element has the same address as the yyv[0] element.
Is it not possible to use expressions for default indexer of managed objects in Visual Studio debugger with C++/CLI?
YYSTYPE is declared as a managed value struct containing a single Object^ reference as follows:
value struct YYSTYPE
{
Object^ obj;
/* Constant integer value */
property long int4
{
long get() { return safe_cast<long>(obj); }
void set(long value) { obj = safe_cast<Object^>(value); }
}
/* Constant floating point value */
property float fp
{
float get() { return safe_cast<float>(obj); }
void set(float value) { obj = safe_cast<Object^>(value); }
}
/* Constant string */
property String^ str
{
String^ get() { return safe_cast<String^>(obj); }
void set(String^ value) { obj = safe_cast<Object^>(value); }
}
/* Expression or Expression Tree */
property ExprC^ exprR
{
ExprC^ get() { return safe_cast<ExprC^>(obj); }
void set(ExprC^ value) { obj = safe_cast<Object^>(value); }
}
/* List of expressions used for parameter lists */
property List<ExprC^>^ exprListR
{
List<ExprC^>^ get() { return safe_cast<List<ExprC^>^>(obj); }
void set(List<ExprC^>^ value) { obj = safe_cast<Object^>(value); }
}
/* List Of instructions */
property InstrListC^ instrListR
{
InstrListC^ get() { return safe_cast<InstrListC^>(obj); }
void set(InstrListC^ value) { obj = safe_cast<Object^>(value); }
}
/* Instruction with actual parameters */
property InstrC^ instrR
{
InstrC^ get() { return safe_cast<InstrC^>(obj); }
void set(InstrC^ value) { obj = safe_cast<Object^>(value); }
}
/* Run-time expression operator */
property OperatorC^ operatorR
{
OperatorC^ get() { return safe_cast<OperatorC^>(obj); }
void set(OperatorC^ value) { obj = safe_cast<Object^>(value); }
}
/* Instruction definition */
property InstrDefC^ instrDefR
{
InstrDefC^ get() { return safe_cast<InstrDefC^>(obj); }
void set(InstrDefC^ value) { obj = safe_cast<Object^>(value); }
}
/* Instruction definition */
property List<String^>^ stringListR
{
List<String^>^ get() { return safe_cast<List<String^>^>(obj); }
void set(List<String^>^ valueIR) { obj = safe_cast<Object^>(valueIR); }
}
};
Added 10-18-12 16:24 PDT I have been able to reproduce this with a much simpler C++/CLI program.
void main()
{
array<int>^ intarray = gcnew array<int>(10);
intarray[0]=0;
intarray[1]=1;
intarray[2]=2;
intarray[3]=3;
intarray[4]=4;
intarray[5]=5;
}
Set breakpoint for last line then enter intarray[3] and intarray[4-1] into watch window. The [4-1] element displays 0.
Today I got the following response to posting this on Microsoft Connect last month:
Greetings from Microsoft Connect! This notification was generated for feedback item:768001
Visual Studio 2012 debugger fails computing index of managed C++/CLI array which you submitted at the Microsoft Connect site. Hello Jon, Thanks for reporting this issue. We do not have a fix yet and have no current plans to fix this in the next release but will consider it for a future release. Thanks again. Marc Paine