Domanda

Ho un pezzo di codice in cui sembra che una variabile stia cambiando alla fine di un blocco di codice pre-processore.

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

Quando eseguo questo nel debugger initialKeyCount = 19969 dopo aver presumibilmente assegnato 20000. Ho giocato un po 'con questo e ho scoperto che l'assegnazione a initialKeyCount è corretta all'interno del primo blocco pre-processore, ma non appena il codice lascia il primo blocco del pre-processore il valore cambia magicamente in 19969.

Questo comportamento è lo stesso indipendentemente dal fatto che la variabile sia dichiarata all'interno o all'esterno del primo blocco pre-processore. Il valore rimane 19969 all'interno del secondo blocco del pre-processore.

Le assegnazioni effettuate in un blocco pre-processore non sono definite all'esterno di quel blocco? Sembra sbagliato ma sembra essere ciò che sta accadendo qui.

È stato utile?

Soluzione

Sembra che Visual Studio sia confuso. Prova questi passaggi in ordine

  1. Utilizza il comando Pulisci
  2. Riavvia Visual Studio
  3. Elimina ogni DLL ed EXE che assomigli anche al tuo programma remoto
  4. Controlla due volte ogni cartella BIN e OBJ per vedere se hai perso qualcosa.
  5. Cerca nel tuo intero disco rigido qualsiasi DLL ed EXE che assomigli anche al tuo programma da remoto ed eliminali anche

Lo vedevo una volta alla settimana presso un'azienda IT per cui lavoravo. Di solito succede quando hai più copie dello stesso progetto, ma l'ho visto anche senza quello.

Altri suggerimenti

Questo tipo di comportamento sembra molto simile al debugger che esegue codice che non corrisponde al codice sorgente che si sta modificando. Sei assolutamente sicuro che le modifiche apportate alla tua sorgente stiano arrivando al codice che stai eseguendo?

I blocchi del preprocessore non sono correlati alla sintassi della lingua. Quindi, hai ragione nel dire che i blocchi del preprocessore non influenzano l'ambito delle definizioni delle variabili.

Sono d'accordo con Greg Hewgill - ho già visto questo genere di cose prima.

Inoltre, trova l'assembly utilizzato dal debugger e aprilo con Reflector. Il disassemblaggio dovrebbe darti un'idea migliore di ciò che sta realmente accadendo.

Di fronte a qualcosa del genere, guardalo a livello di assieme.

Mentre l'assemblaggio è qualcosa che quasi mai codificherai in questi giorni uno BISOGNI per conoscerlo per rintracciare misteri come questo.

Le cose diventano sempre più strane. Ho preso i suggerimenti sopra e ho esaminato il codice con Reflector e lo smontaggio fornito dal debugger, entrambi sembrano come ti aspetteresti. Ho modificato leggermente il codice per mostrare chiaramente la "magia" modifica nella variabile.

Il nuovo codice è

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

Lo smontaggio per quanto sopra è

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 la finestra della memoria ho visto il valore su ebp-0x50 Quando IP è

a 00000094 il valore è 0x0
a 0000009b il valore è 0x4e20
a 0000009e il valore è 0x4e21
a 0000009f il valore è 0x4e01

Devo ammettere che è passato molto tempo da quando ho scritto qualsiasi codice assembly, ma sono abbastanza sicuro che nop non dovrebbe scrivere in memoria. :)

Ovviamente un codice sta eseguendo che il debugger non sta visualizzando. Qualcuno sa se c'è qualcosa su come ho usato il pre-processore che causa questo, o è semplicemente un bug?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top