Visual Studio fails to display some watched expressions
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 operator开发者_StackOverflow中文版s and/or template class objects.
Why is this happening? how do you fix it?
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.
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.
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
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.
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.
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
精彩评论