Question

J'ai un morceau de code dans lequel il apparaît qu'une variable est en train de changer à la fin d'un bloc de code pré-processeur.

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

Lors de l’exécution de cette opération dans le débogueur, initialKeyCount = 19969 après avoir attribué soi-disant 20000. J’ai un peu joué avec cela et constaté que l’affectation à initialKeyCount est correcte dans le premier bloc de pré-processeur, mais dès que le code quitte le premier le pré-processeur bloque la valeur comme par magie en 19969.

Ce comportement est le même, que la variable soit déclarée à l'intérieur ou à l'extérieur du premier bloc pré-processeur. La valeur reste 19969 dans le deuxième bloc de pré-processeur.

Les affectations effectuées dans un bloc de préprocesseur sont-elles indéfinies en dehors de ce bloc? Cela semble faux, mais semble être ce qui se passe ici.

Était-ce utile?

La solution

On dirait que Visual Studio est confus. Essayez ces étapes dans l'ordre

  1. Utilisez la commande Nettoyer
  2. Redémarrez Visual Studio
  3. Supprimez toutes les DLL et tous les fichiers EXE qui, même à distance, ressemblent à votre programme
  4. Vérifiez tous les dossiers BIN et OBJ pour voir s’il vous manque quelque chose.
  5. Recherchez dans votre disque dur tout fichier DLL ou EXE qui ressemble même à distance à votre programme et supprimez-les aussi

Je voyais cela une fois par semaine dans une entreprise informatique pour laquelle je travaillais. Cela se produit généralement lorsque vous avez plusieurs copies du même projet, mais je l’ai vu même sans cela.

Autres conseils

Ce genre de comportement ressemble beaucoup au fait que le débogueur exécute un code qui ne correspond pas au code source que vous éditez. Etes-vous absolument sûr que vos modifications à la source permettent d'atteindre le code que vous utilisez?

Les blocs du préprocesseur ne sont pas liés à la syntaxe du langage. Vous avez donc raison de dire que les blocs de préprocesseur n’affectent pas la portée des définitions de variables.

Je suis d’accord avec Greg Hewgill - j’ai déjà vu ce genre de chose.

Recherchez également l'assemblage utilisé par le débogueur et ouvrez-le à l'aide de Reflector. Le démontage devrait vous donner une meilleure idée de ce qui se passe réellement.

Lorsque vous faites face à quelque chose comme ça, regardez-le au niveau de l'assemblage.

Alors que l'assemblage est quelque chose que vous ne coderez presque jamais de nos jours, il est BESOIN de le savoir pour retracer des mystères comme celui-ci.

Les choses deviennent étrangères et étrangères. J'ai pris les suggestions ci-dessus et examiné le code avec Reflector et le désassemblage fourni par le débogueur, les deux se présentent comme vous le souhaitiez. J'ai légèrement modifié le code pour indiquer clairement le symbole "magique". changer dans la variable.

Le nouveau code est

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

Le démontage pour ce qui précède est

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

En utilisant la fenêtre de mémoire, j'ai regardé la valeur à ebp-0x50 Quand IP est

à 00000094 la valeur est 0x0
à 0000009b la valeur est 0x4e20
à 0000009e la valeur est 0x4e21
à 0000009f la valeur est 0x4e01

J'admets que cela faisait très longtemps que je n'ai écrit aucun code d'assemblage, mais je suis assez confiant que nop ne devrait pas écrire dans la mémoire. :)

Évidemment, du code en cours d'exécution que le débogueur n'affiche pas. Est-ce que quelqu'un sait s'il y a quelque chose dans la façon dont j'ai utilisé le pré-processeur qui cause ceci, ou s'il s'agit simplement d'un bug?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top