arraysvisual-studioc++-clivisual-studio-debuggingwatch-window

Visual Studio 2012 debugger fails computing index of managed C++/CLI array


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.

Watch Window

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.

enter image description here

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.


Solution

  • 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