2009-11-24 12 views
11

En Visual Studio, la mayoría de mis objetos y variables no se pueden resolver durante una sesión de depuración por varias razones. Esto significa que no puedo inspeccionar ni mirar objetos o invocar sus funciones, lo que hace que sea extremadamente difícil depurar mi código porque la mayoría de mis expresiones simplemente no funcionarán. Algunos errores típicos que recibo al añadir una expresión a la ventana de inspección incluyen:Visual Studio no puede mostrar algunas expresiones observadas

  • CXX0019: Error: mal tipo fundido
  • CXX0059: Error: operando de la izquierda es la clase no es un nombre de función
  • CXX0058: Error: operador sobrecargado no encontrado

En la mayoría de los casos, estas expresiones involucran operadores sobrecargados y/o objetos de clase de plantilla.

¿Por qué sucede esto? ¿Como lo arreglas?

+0

¿Puedes publicar algunas expresiones? Usar las ventanas de observación con algeritms complejas (operadores) es pedir problemas imho – RvdK

Respuesta

8

Los errores que tiene se deben a limitaciones en el depurador, no hay errores como implica Daniel.

La ventana del reloj no puede llamar a los operadores sobrecargados. Si tiene, por ejemplo, a std::vector<int> vecSomething no puede poner vecSomething[0] en la ventana del reloj, porque std::vector<int>::operator[] es un operador sobrecargado. En consecuencia, para un vector de objetos, no puede hacer vecObject[0].SomeMemberVariableOfObject en la ventana de observación. Puede escribir vecObject._Myfirst[0].SomeMemberVariableOfObject. En la implementación de STL de Visual Studio, _Myfirst es un miembro del vector que apunta al primer elemento.

Si agrega sus propias variables y tipos a la ventana del reloj, agregue relojes a los miembros de datos directamente. No es problema seguir cadenas de punteros como member.memberStruct.ptrToObj->memberOfObj.

Editar:

En realidad Visual Studio puede llamar al código en la ventana Inspección: http://geekswithblogs.net/sdorman/archive/2009/02/14/visual-studio-2008-debugging-ndash-the-watch-window.aspx

Por lo tanto, es un poco un misterio por qué no se pueden utilizar operadores sobrecargados.

+3

la ventana del reloj ejecuta el código – stijn

+0

@stijn: ¿Pueden dar más detalles? Sí evalúa expresiones, es decir, puede ver "(a + b)/2", evalúa código para formatear expresiones siguiendo las reglas dadas en autoexp.dat, pero ¿cuándo ejecuta mi código? – Sebastian

+0

@stijn: Actualicé mi publicación. Descubrí que tienes razón, se permite llamar a funciones en la ventana del reloj. No lo sabía. – Sebastian

4

Why is this happening?

La herramienta tiene sus limitaciones. Por ejemplo, muchas veces "voy a la definición" y no se encuentra la definición. Tengo que "encontrar en los archivos". No es de extrañar que algunas expresiones no se evalúen durante las sesiones de depuración, tampoco.

How do you fix it?

  • Mantener expresiones simples. No concatenarlos directamente, use variables con nombres explicativos para resultados intermedios.
  • Admite tu código con aserciones explícitas. Si es "incorrecto", una afirmación debería fallar.
+0

No recuerdo, ¿hay un operador de afirmación nativa en C++? ¿O debe uno idear el suyo? Además, ¿cree que sería útil escribir funciones de contenedor como interfaces para expresiones comúnmente inspeccionadas para evitar esta limitación de depurador? Eso implica un poco más de gastos generales de programación, pero no puedo pensar en un mejor enfoque todavía. –

+0

@Jonny assert es una macro. Normalmente es definido por el proveedor del compilador. Y sí, escribir funciones adicionales ayudaría a aclarar lo que está sucediendo. –

5

El problema y las posibles soluciones se describen precisamente en este Microsoft Documentation

The managed expression evaluator accepts most expressions written in Visual C++. The following topics offer specific information and discuss some of the expression types that are not supported:

Identifiers and Types 
Function Evaluation 
Operators 
Overloaded Operators 
Strings 
Casts 
Object Comparison and Assignment 
typeof and sizeof Operators 
Boxing 
Property Evaluation 
+0

Gracias, sin embargo, observo que la documentación parece ser incorrecta para VS2008: dice que el 'operador []()' sobrecargado funcionará, pero al agregar un reloj 'v [42]' para una variable 'vector v' se obtiene el Error CXX0058 - incluso si '42' cambia a' 42U' o '42L' o' 42LU' para satisfacer el requisito de coincidencia exacta de argumentos. Tal vez no funcione w.r.t. ¿plantillas? –

+0

@j_random_hacker Tal vez sea por la plantilla, no lo sé porque nunca utilicé VS2008. Cuando el operador '[]' no funciona en la ventana del reloj, puede mostrar los miembros internos de la clase vectorial y agregar un desplazamiento para ver los datos que desea ver, pero esto es bastante más lento que escribir 'v [42] '. –

2

de gestión de archivos PDB está lejos de ser perfecta, sobre todo en proyectos de mayor envergadura. En particular, VS tiene el comportamiento bastante estúpido de fusionar todos los símbolos en VSxx.PDB, incluso en diferentes proyectos. El modificador/Fd puede arreglar esto fácilmente; pase $(TargetDir)$(TargetName).pdb o algo similar.

1

Encontré una solución que resuelve (hasta cierto punto) el problema de los operadores sobrecargados. Parece que no depende de los aspectos internos de la clase. Tienes que usar la forma expandida de la llamada del operador. Aquí hay un ejemplo para vector<int> v:

v.operator[](0) 

he comprobado en Visual C++ 2012.

1

Puede ser debido a clases anidadas
Ejemplo:

 
    class A 
    { 
     class B 
     { 
      int i; 
     }; 
    }; 

fundido como (B *) (0x12345678) fallará, pero (A :: B *) (0x12345678) tendrá éxito

Cuestiones relacionadas