Visual Studio fails to display some watched expressions
Asked Answered
C

6

15

In Visual Studio, most of my objects and variables cannot be resolved during a debugging session for various reasons. This means I cannot inspect or watch objects or their invoke their functions making it extremely difficult to debug my code because most of my expressions simply won't work. Some typical errors I get when adding an expression to the watch window include:

  • CXX0019: Error: bad type cast
  • CXX0059: Error: left operand is class not a function name
  • CXX0058: Error: overloaded operator not found

Most often these expressions involve overloaded operators and/or template class objects.

Why is this happening? how do you fix it?

Coraciiform answered 24/11, 2009 at 8:38 Comment(1)
can you post some expressions? using the watch windows with complex algeritms(operators) is asking for troubles imhoDarius
L
10

The errors you have are due to limitations in the debugger, there are not bugs as Daniel implies.

The watch window cannot call overloaded operators. If you have e.g. a std::vector<int> vecSomething you cannot put vecSomething[0] into the watch window, because std::vector<int>::operator[] is an overloaded operator. Consequently, for a vector of objects, you cannot do vecObject[0].SomeMemberVariableOfObject in the watch window. You could write vecObject._Myfirst[0].SomeMemberVariableOfObject. In Visual Studio's STL implementation, _Myfirst is a member of vector pointing at the first element.

If you add your own variables and types to the watch window, add watches to the data members directly. It is no problem to follow chains of pointers like member.memberStruct.ptrToObj->memberOfObj.

Edit:

Actually Visual Studio can call code in the Watch window: http://geekswithblogs.net/sdorman/archive/2009/02/14/visual-studio-2008-debugging-ndash-the-watch-window.aspx

Thus, it is slightly mysterious why overloaded operators cannot be used.

Leede answered 24/11, 2009 at 8:57 Comment(3)
@stijn: Can you elaborate? It does evaluate expressions, i.e., you can watch "(a+b)/2", it does evaluate code to format expressions following rules given in autoexp.dat, but when does it execute my code?Leede
@stijn: Updated my post. I found out that you are right, calling functions is allowed in the watch window. I didn't know that.Leede
I think I recall seeing overloaded operator functions being evaluated in the watch window "once in a blue moon" but most often they definitely do not evaluate.Coraciiform
L
4

Why is this happening?

The tool has its limitations. For example, many times I "go to definition" and the definition is not found. I have to "find in files". It is no surprise that some expressions are not evaluated during debugging sessions, either.

How do you fix it?

  • Keep expressions simple. Do not concatenate them directly, use variables with explanatory names for intermediate results.
  • Support your code with explicit assertions. If it's "wrong", an assertion should fail.
Lutes answered 24/11, 2009 at 8:47 Comment(2)
I cannot remember, is there a native assert operator in C++? Or must one devise their own? Moreover, do you think it would work to write wrapper functions as interfaces to commonly inspected expressions to work-around this debugger limitation? That incurs a little more programming overhead, but I cannot think of a better approach just yet.Coraciiform
@Jonny assert is a macro. It is typically defined by the compiler vendor. And yes, writing extra functions would help clarify what's going on.Lutes
F
4

The problem and possible workarounds are precisely described in this Microsoft Documentation

The debugger accepts most Microsoft and ANSI C/C++ expressions; however, you do need to be aware of the following:

Unsupported Operators and Additional Operators

Restrictions on Native C++ Expressions

Fulviah answered 3/12, 2012 at 21:40 Comment(4)
Thanks, however I note that the documentation appears to be wrong for VS2008: it says that overloaded operator[]() will work, but adding a watch v[42] for a variable vector<int> v gives the CXX0058 error -- even if 42 is changed to 42U or 42L or 42LU to satisfy the requirement of exact type matching of arguments. Maybe it doesn't work w.r.t. templates?Spermary
@Spermary Maybe it is because of the template, I don't know since I never used VS2008. When the [] operator doesn't work in the watch window you can display the internal members of the vector Class and add an offset to watch the data you want to see, but this is quite slower than typing v[42].Keelykeen
The linked documentation is for managed C++. i.e. C++/CLI. Different evaluator, different supported functionality. It's not relevant to the original question. Boxing and properties don't even exist in C++ as first class concepts. From the linked page you can get to correct docs for native code. learn.microsoft.com/en-us/previous-versions/visualstudio/…Stuff
@Stuff I changed the link.Keelykeen
S
3

I found one solution which solves (to some extent) the issue of overloaded operators. It seems to not depend on the internals of the class. You have to use the expanded form of the operator call. Here's an example for vector<int> v:

v.operator[](0)

I tested it in Visual C++ 2012.

Scrawly answered 18/10, 2013 at 22:8 Comment(1)
With the operator call for a map in VS2010 says: 'CX0039: Error: symbol is ambiguous'Jokjakarta
P
2

PDB file management is far from perfect, certainly in larger projects. In particular, VS has the rather stupid behavior of merging all symbols in VSxx.PDB, even across different projects. The /Fd switch can easily fix this; pass $(TargetDir)$(TargetName).pdb or something similar.

Polarize answered 4/12, 2012 at 9:8 Comment(0)
D
1

It can be due to nested classes
Example :

    class A
    {
        class B
        {
            int i;
        };
    };

cast like (B*)(0x12345678) will fail, but (A::B*)(0x12345678) will succeeded

Discontinue answered 15/2, 2014 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.