Целочисленное значение изменяется при выходе из блока препроцессора - PullRequest
1 голос
/ 06 января 2009

У меня есть фрагмент кода, где кажется, что переменная изменяется в конце блока препроцессора кода.

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

При выполнении этого в отладчике initialKeyCount = 19969 после предположительного присвоения 20000. Я немного поиграл с этим и обнаружил, что присвоение initialKeyCount является правильным внутри первого блока препроцессора, но как только код покидает первый блок препроцессора магически меняет значение на 19969.

Это поведение одинаково независимо от того, объявлена ​​ли переменная внутри или снаружи первого блока препроцессора. Значение остается 19969 внутри второго блока препроцессора.

Не определены ли назначения, сделанные в блоке препроцессора, вне этого блока? Это кажется неправильным, но похоже, что то, что здесь происходит.

Ответы [ 5 ]

1 голос
/ 06 января 2009

Такое поведение очень похоже на то, что отладчик выполняет код, который не соответствует исходному коду, который вы редактируете. Вы абсолютно уверены, что ваши исходные изменения вносят свой вклад в код, который вы запускаете?

Блоки препроцессора не связаны с синтаксисом языка. Итак, вы правы, говоря, что блоки препроцессора не влияют на область определения переменных.

0 голосов
/ 06 января 2009

Похоже, что Visual Studio запуталась. Попробуйте эти шаги в порядке

  1. Используйте команду очистки
  2. Перезапустите Visual Studio
  3. Удалите все DLL и EXE, которые даже удаленно похожи на вашу программу
  4. Дважды проверьте каждую папку BIN и OBJ, чтобы убедиться, что вы что-то пропустили.
  5. Поиск на вашем жестком диске любых DLL и EXE, которые даже отдаленно похожи на вашу программу, и удаление их тоже

Раньше я видел это раз в неделю в ИТ-компании, в которой работал. Обычно это происходит, когда у вас есть несколько копий одного проекта, но я видел это даже без этого.

0 голосов
/ 06 января 2009

Вещи становятся незнакомыми и незнакомыми. Я принял вышеуказанные предложения и изучил код с помощью 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 не должен записывать в память. :)

Очевидно, что выполняется некоторый код, который не отображается отладчиком. Кто-нибудь знает, если есть что-то о том, как я использовал препроцессор, который вызывает это, или это просто ошибка?

0 голосов
/ 06 января 2009

Когда сталкиваетесь с чем-то подобным, посмотрите на это на уровне сборки.

Хотя сборка - это то, что вы почти никогда не будете кодировать в наши дни, одна НУЖНА , чтобы узнать, как отследить подобные загадки.

0 голосов
/ 06 января 2009

Я согласен с Грегом Хьюгиллом - я видел подобные вещи раньше.

Также найдите сборку, которую использует отладчик, и откройте ее с помощью Reflector. Разборка должна дать вам лучшее представление о том, что на самом деле происходит.

...