views:

95

answers:

5

I have a chunk of code where it appears that a variable is changing at the end of a pre-processor block of code.

int initialKeyCount;
#if(DEBUG)
//          int initialKeyCount = _root.CountAllKeys();
      initialKeyCount = 20000;
#endif
      currNode = currNode.EnsureDegreeKeysPresent(parent); //initialKeyCount = 19969 here
#if(DEBUG)
      int currentKeyCount = _root.CountAllKeys();
      Debug.Assert(initialKeyCount == currentKeyCount,
               string.Format("EnsureDegreeNodesPresent changed the node count from {0} to {1}.", initialKeyCount, currentKeyCount));
#endif

When executing this in the debugger initialKeyCount = 19969 after supposedly assigning 20000. I have played around with this a bit and found that assignment to initialKeyCount is correct inside the first pre-processor block, but as soon as the code leaves the first pre-processor block the value magically changes to 19969.

This behavior is the same regardless of whether the variable is declared inside or outside the first pre-processor block. The value remains 19969 inside the second pre-processor block.

Are assignments made in a pre-processor block undefined outside of that block? That seems wrong but appears to be what is happening here.

+1  A: 

This sort of behaviour sounds very much like the debugger is running code that doesn't match the source code you are editing. Are you absolutely sure that your source changes are making it all the way to the code you're running?

The preprocessor blocks are unrelated to the language syntax. So, you're correct in saying that preprocessor blocks do not affect the scope of variable definitions.

Greg Hewgill
A: 

I agree with Greg Hewgill - I have seen this sort of thing before.

Also, find the assembly the debugger is using and open it with Reflector. The dissassembly should give you a better idea of what is actually happening.

Andrew Kennan
A: 

When faced with something like this, look at it at the assembly level.

While assembly is something you will almost never code in these days one NEEDS to know it to trace down mysteries like this.

Loren Pechtel
A: 

Things get stranger and stranger. I took the above suggestions and examined the code with Reflector and the disassembly provided by the debugger, both look as you would expect. I modified the code slightly to clearly show the "magic" change in the variable.

The new code is

int initialKeyCount;
#if(DEBUG)
//          int initialKeyCount = _root.CountAllKeys();
      initialKeyCount = 20000;
      initialKeyCount++;
      initialKeyCount = initialKeyCount;
#endif
      currNode = currNode.EnsureDegreeKeysPresent(parent);
#if(DEBUG)
      int currentKeyCount = _root.CountAllKeys();
      Debug.Assert(initialKeyCount == currentKeyCount,
               string.Format("EnsureDegreeNodesPresent changed the node count from {0} to {1}.", initialKeyCount, currentKeyCount));
#endif

The disassembly for the above is

int initialKeyCount;
#if(DEBUG)
//          int initialKeyCount = _root.CountAllKeys();
      initialKeyCount = 20000;
00000094  mov         dword ptr [ebp-50h],4E20h 
      initialKeyCount++;
0000009b  inc         dword ptr [ebp-50h] 
      initialKeyCount = initialKeyCount;
0000009e  nop              
#endif
      currNode = currNode.EnsureDegreeKeysPresent(parent);
0000009f  mov         edx,dword ptr [ebp-48h] 
...

Using the memory window I watched the value at ebp-0x50 When IP is

at 00000094 the value is 0x0
at 0000009b the value is 0x4e20
at 0000009e the value is 0x4e21
at 0000009f the value is 0x4e01

I'll admit it's been a LONG time since I wrote any assembly code, but I'm pretty confident that nop shouldn't be writing to memory. :)

Obviously some code is executing that the debugger is not displaying. Does anyone know if there is something about how I've used the pre-processor that causes this, or is this simply a bug?

ScottS
A: 

Sounds like Visual Studio got confused. Try these steps in order

  1. Use the Clean command
  2. Restart Visual Studio
  3. Delete every DLL and EXE that even remotely looks like your program
  4. Double check every BIN and OBJ folder to see if you missed anything.
  5. Search your whole hard drive for any DLL and EXE that even remotely looks like your program and delete them too

I used to see this once a week at an IT company I worked for. It usually happens when you have multiple copies of the same project, but I've seen it even without that.

Jonathan Allen
Simply restarting VS didn't fix the issue, but a couple days and a reboot seems to have made it go away.
ScottS