I'm having a really bizarre problem wherein the watch window values for some variables don't seem to match their "real world" values. The debugger just appears to be off in space. Here's the tiniest code snippet that shows it:
printf("%d", pNodes[nNode].nColumn); // watch shows "4"
printf("%d", nColumn); // watch shows "1"
if (pNodes[nNode].nColumn != nColumn)
continue; // this is NOT called
So here's the behaviour:
- If I add a watch to
pNodes[nNode].nColum开发者_StackOverflow中文版n
, it shows a value of4
. - If I add a watch to
nColumn
, it shows a value of1
. - If I check the expression
pNodes[nNode].nColumn != nColumn
in the watch window, it evaluates totrue
. - The
continue
statement is skipped! - I added the
printf()
calls to see what was going on, and theprintf()
prints the values1
and1
, which seems to agree with the way the code "flows" (i.e. that it does not call thecontinue
inside theif
statement.
I can even check the memory at &pNodes(nNode].nColumn
, and the memory shows the "incorrect" values that the watch window is showing me. So it seems like the debugger is getting completely "disconnected" from the actual program data or something. I'm running a debug build optimizations are turned off. I've also checked that pNodes does not correspond to some global variable or other variable higher in scope -- it seems there's only a local version.
This is completely baffling to me! I'm not even sure where to go next to try to figure out the problem. If you have any ideas whatsoever, I'd love to hear them!
Thanks!
So I think I've cracked the case: The culprit was Struct Member Alignment. I had a bunch of projects mixed together and some of them had varying values for this field inside the projects. I removed the settings on all of them to just let VS pick the defaults and the problem has disappeared.
The applicable value was between 4 bytes in some of the projects, Default in some of the projects, and empty altogether in others. The value is under Configuration Properties/ C/C++ / Code Generation / Struct Member Alignment. Again, I ended up just deleting the values altogether for the projects. I think this was set on the projects at some point in the past to deal with some kind of cross-platform issue, but at least it's fixed for the work I'm doing now!
Thanks for all of your help!
If watches are set using variables not in scope, that is the sort of behavior I see all the time with Visual Studio. It really should say "<not in scope>" or something more useful.
If you are stepping through these lines of code and you still see those ghostly values, I don't know: are you sure it is a debug build?
Visual Studio 2010 debugger has issues with tracking watch variable memory locations. Sometimes it will mislead you badly because VS2010 is NOT showing you the variable you think it is showing you.
For example, if you re-use a variable name within a function, so which memory location should be displayed in the watch window CHANGES as the execution scope changes:
for (int i=0; i<10; i++) {
i=i+1; // do something, what isn't important
}
int i;
for (i=0; i<5; i++) {
i=i+1; // do something
}
printf("i=%d\n", i);
Now put the variable i in the watch window.
Obviously, which i (or value) is displayed in the watch window matters. If you run the program, you will see that as it enters the for-loop the watch tracks the i variable of the for loop. When it exits the for loop, and then hits the code below with the other variable with the same name the watch window isn't tracking that variable's memory.
You will see the watch window still declaring i is 10, even though in the 2nd loop i is now 0,1,2,... and after the 2nd loop i is actually 6, but the watch window still declares i is 10.
And what should the watch window do? I would argue, it should always show you the value of the variable with that watch name, that is in scope, as the language rules tell you only one of those variables is in scope at any given time.
Its a bug in the debugger's watch window functionality here (VS2010 seems to cheaply just find the first variable in the function that matches the name you gave it in the watch, and doggedly watch THAT memory space, regardless of what else may be in the code, even if a new variable with the same name has taken over scope (at which point the watch window is now lying to you!)
精彩评论