La valeur entière change lorsque vous quittez le bloc du préprocesseur
-
03-07-2019 - |
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.
La solution
On dirait que Visual Studio est confus. Essayez ces étapes dans l'ordre
- Utilisez la commande Nettoyer
- Redémarrez Visual Studio
- Supprimez toutes les DLL et tous les fichiers EXE qui, même à distance, ressemblent à votre programme
- Vérifiez tous les dossiers BIN et OBJ pour voir s’il vous manque quelque chose.
- 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?