0

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.

JonN
  • 2,498
  • 5
  • 33
  • 49
  • There's lots of ways to ask for trouble when you force the compiler to box unmanaged structure values. The debugger gets stupid in general, it has no idea what the actual type of element might be. Seeing the same pointer is certainly possible, a boxed value is a reference type. You can post this to connect.microsoft.com but don't get your hopes up. – Hans Passant Oct 18 '12 at 19:40
  • @HansPassant Actually the YYSTYPE is not an unmanaged struct. It's a **value struct**. I edited original question to show this. So I'm confused as to why this shouldn't work. I tried casting the constants using Int32(4-1) but it still displayed element 0. The alarming thing is that it doesn't give me an error it just displays element 0 with no complaints. By the way it does display correctly if an integer variable is used for the index **yyv[x]** but not if it includes an expression. **yyv[x-1]** fails. – JonN Oct 18 '12 at 21:04

1 Answers1

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

JonN
  • 2,498
  • 5
  • 33
  • 49