Pergunta

I tem um pedaço de código quando se verifica que uma variável está a mudar no final de um bloco de pré-processador de código.

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

Ao executar este no depurador initialKeyCount = 19969 após supostamente atribuindo 20000. Eu tenho jogado ao redor com esta um pouco e descobriu que a atribuição de initialKeyCount está correta dentro do primeiro bloco pré-processador, mas assim que as folhas código do primeiro pré-processador de bloco o valor muda magicamente para 19969.

Este comportamento é o mesmo independentemente do facto da variável é declarado no interior ou no exterior do primeiro bloco de pré-processador. O valor permanece 19969 no interior do segundo bloco de pré-processador.

São atribuições feitas em um bloco de pré-processador indefinido fora desse bloco? Isso parece errado, mas parece ser o que está acontecendo aqui.

Foi útil?

Solução

soa como Visual Studio ficou confuso. Experimente estes passos, a fim

  1. Use o comando Limpar
  2. Reiniciar Visual Studio
  3. Excluir todas as DLL e EXE que se parece nem remotamente parecido com o seu programa
  4. Verifique cada pasta BIN e OBJ para ver se você perdeu alguma coisa.
  5. Procure em seu disco rígido inteiro para qualquer DLL e EXE que olha mesmo remotamente parecido com o seu programa e excluí-los demasiado

Eu costumava ver isso uma vez por semana em uma empresa de TI que eu trabalhava. Isso geralmente acontece quando você tem várias cópias do mesmo projeto, mas eu vi isso, mesmo sem isso.

Outras dicas

Este tipo de comportamento parece muito com o depurador está sendo executado código que não coincide com o código-fonte que você está editando. Você está absolutamente certo de que sua fonte mudanças estão fazendo todo o caminho para o código que você está correndo?

Os blocos do pré-processador não estão relacionados com a sintaxe da linguagem. Então, você está correto em dizer que os blocos do pré-processador não afectar o âmbito de definições de variáveis.

Eu concordo com Greg Hewgill - Eu já vi esse tipo de coisa antes.

Além disso, encontrar a montagem do depurador está usando e abri-lo com refletor. A desmontagem deve lhe dar uma idéia melhor do que está realmente acontecendo.

Quando confrontados com algo como isso, olhar para ele no nível da montagem.

Enquanto montagem é algo que você quase nunca código nestes dias um necessidades para conhecê-lo para rastrear mistérios como este.

As coisas ficam mais estranho. Tomei as sugestões acima e examinou o código com reflector e a desmontagem fornecido pelo depurador, tanto visual como seria de esperar. Eu modifiquei o código ligeiramente para mostrar claramente a mudança "mágica" na variável.

O novo código é

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

A desmontagem para o acima é

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

Usando a janela de memória Eu assisti o valor em ebp-0x50 Quando IP é

at 00000094 o valor é 0x0
em 0000009b o valor é 0x4e20
em 0000009e o valor é 0x4e21
em 0000009f o valor é 0x4e01

Eu vou admitir que tem sido um longo tempo desde que eu escrevi qualquer código de montagem, mas estou bastante confiante de que nop não deve ser escrita na memória. :)

Obviamente algum código está em execução que o depurador não está exibindo. Alguém sabe se há algo sobre como eu usei o pré-processador que faz isso, ou é simplesmente um bug?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top