Pregunta

Tengo un fragmento de código en el que parece que una variable está cambiando al final de un bloque de código preprocesador.

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

Al ejecutar esto en el depurador initialKeyCount = 19969 después de supuestamente asignar 20000. He jugado un poco con esto y descubrí que la asignación a initialKeyCount es correcta dentro del primer bloque de preprocesador, pero tan pronto como el código sale del primer preprocesador bloquea el valor mágicamente cambia a 19969.

Este comportamiento es el mismo independientemente de si la variable se declara dentro o fuera del primer bloque de preprocesador. El valor permanece 19969 dentro del segundo bloque de preprocesador.

¿Las asignaciones realizadas en un bloque preprocesador están indefinidas fuera de ese bloque? Eso parece incorrecto, pero parece ser lo que está sucediendo aquí.

¿Fue útil?

Solución

Suena como que Visual Studio se confundió. Prueba estos pasos en orden

  1. Utilice el comando Limpiar
  2. Reiniciar Visual Studio
  3. Eliminar todas las DLL y EXE que se parezcan remotamente a su programa
  4. Verifique dos veces cada carpeta BIN y OBJ para ver si se perdió algo.
  5. Busque en su disco duro completo cualquier DLL y EXE que se parezca remotamente a su programa y elimínelos también

Solía ??ver esto una vez por semana en una empresa de TI para la que trabajaba. Normalmente ocurre cuando tienes varias copias del mismo proyecto, pero lo he visto incluso sin eso.

Otros consejos

Este tipo de comportamiento suena muy parecido a que el depurador está ejecutando un código que no coincide con el código fuente que está editando. ¿Estás absolutamente seguro de que los cambios en tu fuente están llegando al código que estás ejecutando?

Los bloques del preprocesador no están relacionados con la sintaxis del lenguaje. Por lo tanto, tiene razón al decir que los bloques del preprocesador no afectan el alcance de las definiciones de variables.

Estoy de acuerdo con Greg Hewgill, he visto este tipo de cosas antes.

También, encuentre el ensamblaje que está utilizando el depurador y ábralo con Reflector. El desmontaje debería darle una mejor idea de lo que realmente está sucediendo.

Cuando te enfrentes a algo como esto, míralo a nivel de ensamblaje.

Si bien el ensamblaje es algo que casi nunca codificará en estos días uno NECESITA saberlo para rastrear misterios como este.

Las cosas se ponen cada vez más extrañas. Tomé las sugerencias anteriores y examiné el código con Reflector y el desmontaje proporcionado por el depurador, ambos se ven como era de esperar. Modifiqué el código ligeramente para mostrar claramente la " magia " cambio en la variable.

El nuevo código es

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

El desmontaje de lo anterior es

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 ventana de memoria observé el valor en ebp-0x50 Cuando la IP es

en 00000094 el valor es 0x0
en 0000009b el valor es 0x4e20
en 0000009e el valor es 0x4e21
en 0000009f el valor es 0x4e01

Admito que ha pasado MUCHO tiempo desde que escribí cualquier código de ensamblaje, pero estoy bastante seguro de que nop no debería estar escribiendo en la memoria. :)

Obviamente, se está ejecutando algún código que el depurador no está mostrando. ¿Alguien sabe si hay algo acerca de cómo he usado el preprocesador que causa esto, o es simplemente un error?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top