I try to debug my program and set brake points, so I can examine the
variables, using the watch windows. This is what I have observed in
the watch window.
- A variable that is active in the function at the brake point either
has the WRONG VALUE or it has the message
"Expression cannot be evaluated". This is not a case of bad memory.
It happens with variables that are in scope, not just with pointers.
Sometimes they actually have the correct value displayed but, as soon
as I hit F10, they either get the wrong value or give me "Expression
cannot be evaluated".
I never had these problems with versions 4 through 7. Neither have I
had them with any debuggers, on Unix or VMS, ever since I started
using code debuggers in the 80s. Does anyone know why version 8 is so
abominable (at least on my PC)?
Thanks,
Peter.
A break point on a line means that you're pausing programming
execution *just prior* to the execution of the statement on that
line. Hit F10 to step forward one, and you'll see the results of that
execution. Hit F11, and you can step into the function calls that
make up that statement. (Including construction of temporary objects)
Try setting a data breakpoint (a breakpoint that triggers when the
value at an address changes). When it's hit, you'll notice that VS
will indicate that the "current line" is the one *following* the line
that changed the data at that address.
The "expression cannot be evaluated" usually means that you haven't
fully stepped into the function's scope, or that the object in
question hasn't had its constructor run yet.
The only other thing I can suggest is that you make sure that you
include your relevant header files in the cpp files that need them,
and not just in stdafx.h. I've seen VS2008 fail to parse classes when
those class definitions were only referenced in stdafx.h, and not in
the cpp files themselves.
> I never had these problems with versions 4 through 7. Neither have I
I only used VS2003 for a short while, but I'm fairly certain it had
the same behavior wrt breakpoint execution patterns. I don't know
about earlier versions.
> had them with any debuggers, on Unix or VMS, ever since I started
> using code debuggers in the 80s.
Visual Studio isn't available on Unix, VMS or any such platform that I
know of. (More's the pity; I'm a Linux coder/user at home and a
Windows coder at work. Even Eclipse doesn't match the utility I get
out of VS2005 and VS2008 at work.)
> Does anyone know why version 8 is so
> abominable (at least on my PC)?
Because you're not used to them? If you've been coding since the 80s,
surely you've learned that the number one complaint from users is when
their interface changes. (And this certainly sounds like an interface
issue. I've never had Visual Studio's debugger indicate bad results
that weren't the result of the code being buggy.)
Thank you very much for your reply. I checked my project settings and
found that I had build it in release mode (the default). I rebuilt it
in debug mode and the problem appears to have gone away. Even so, I
never had this problem with pre-.net versions or with version 7
( guess .net 2003). Giving the wrong values seems like a strange way
to respond to the code being inadvertently build in release mode.
Thanks again,
Peter.
(You probably know this bit if you've been coding for 20 years, but
I'll go over it anyay for the sake of newsgroup archives) When you
build in Release mode, you're typically enabling a swath of
optimizations that give the compiler license to refactor code as long
as it maintains that code's behavior. Some of these optimizations
lead to reordering of instructions, inlining of functions, and
wholesale removal of some statements and functions. What this means
is that while your debugger will know roughly where in the source file
your code pointer and stack sit, there will be differences between the
code you wrote and the code that actually runs. Barring compiler bugs
and use of undefined behavior*, the interactive behavior of the
program when compiled in Release mode should be identical to as when
it is compiled in Debug. The program will still get from point A to
point B. The way it gets from here to there may differ.
When you see an incorrect value in this case, you're most likely
seeing Visual Studio's debugger making an incorrect guess at the
meaning of a symbol; The PDB files Win32 debuggers use don't provide
enough information to reverse engineer the optimizations the compiler
made in all cases, so it will be hit or miss. If you see "This
expression cannot be evaluated", you might be seeing the result of a
bad guess (if it's a complicated type like a CString), or you might be
seeing the debugger recognize that the variable doesn't exist in a
form it can identify.
Getting quirky variable readings is a side-effect of powerful
optimization routines. If you're concerned you won't be able to
interpret crash dumps, try turning off different optimizations on your
project settings until you find a combination that runs sufficiently
quickly, but still produces meaningful dumps.
* You'll see this term bandied about on comp.lang.c++ a lot.
"Undefined behavior" is any behavior that the standard doesn't ban,
but also doesn't explicitly ensure will work. It's up to the compiler
writer to decide how his compiler will treat code using undefined
behavior, and how it treats it with optimizations enabled is entirely
up to the compiler.