1

我有一段代码,其中似乎变量在预处理器代码块的末尾发生了变化。

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

在应该分配 20000 之后在调试器中执行此操作时,initialKeyCount = 19969。我已经玩了一点,发现在第一个预处理器块内分配给 initialKeyCount 是正确的,但是一旦代码离开第一个预处理器阻止值神奇地更改为 19969。

无论变量是在第一个预处理器块内部还是外部声明,此行为都是相同的。该值在第二个预处理器块内保持为 19969。

预处理器块中的分配是否在该块之外未定义?这似乎是错误的,但似乎就是这里发生的事情。

4

5 回答 5

1

这种行为听起来很像调试器正在运行的代码与您正在编辑的源代码不匹配。您是否绝对确定您的源代码更改一直到您正在运行的代码?

预处理器块与语言语法无关。因此,您说预处理器块不会影响变量定义的范围是正确的。

于 2009-01-06T00:18:36.220 回答
0

我同意 Greg Hewgill 的观点——我以前见过这种事情。

此外,找到调试器正在使用的程序集并使用 Reflector 打开它。反汇编应该让您更好地了解实际发生的情况。

于 2009-01-06T00:25:08.767 回答
0

当遇到这样的事情时,请从装配级别来看。

虽然汇编是你现在几乎永远不会编码的东西,但需要知道它才能追查这样的谜团。

于 2009-01-06T00:29:53.623 回答
0

事情变得越来越陌生。我接受了上述建议,并使用 Reflector 和调试器提供的反汇编检查了代码,两者看起来都如您所愿。我稍微修改了代码以清楚地显示变量中的“神奇”变化。

新代码是

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

上面的拆解是

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] 
...

使用内存窗口我观察了 ebp-0x50 当 IP 为

在 00000094 处的值为 0x0
在 0000009b 处的值为 0x4e20
在 0000009e 处的值为 0x4e21
在 0000009f 处的值为 0x4e01

我承认自从我编写任何汇编代码以来已经很久了,但我非常有信心 nop 不应该写入内存。:)

显然,一些代码正在执行,但调试器没有显示。有谁知道我是如何使用导致这种情况的预处理器的,或者这只是一个错误?

于 2009-01-06T01:40:29.847 回答
0

听起来 Visual Studio 很困惑。按顺序尝试这些步骤

  1. 使用清理命令
  2. 重新启动 Visual Studio
  3. 删除所有看起来像你的程序的 DLL 和 EXE
  4. 仔细检查每个 BIN 和 OBJ 文件夹,看看是否遗漏了任何内容。
  5. 在您的整个硬盘驱动器中搜索任何看起来像您的程序的 DLL 和 EXE,并将它们也删除

我曾经在我工作的一家 IT 公司每周看到一次。当您拥有同一个项目的多个副本时,通常会发生这种情况,但即使没有这个,我也见过。

于 2009-01-06T02:48:31.083 回答