¿Cuál es el código "no utilizado" más simple que no se optimizará?

Con mucha frecuencia, quiero probar el valor de una variable en una función a través de un punto de interrupción. En muchos casos, esa variable nunca es referenciada por ningún código que "haga cosas", pero eso no significa que todavía no quiera verla. Desafortunadamente, el optimizador está trabajando en mi contra y simplemente elimina todo ese código al compilar, por lo que tengo que idear una grosería enrevesada para engañar al compilador haciéndole creer que esos valores realmente importan para que no se optimicen. No quiero desactivar el optimizador, ya que está haciendo cosas importantes en otros lugares, pero solo para este bloque de código me gustaría desactivarlo temporalmente por el bien de la depuración.

preguntado el 28 de julio de 12 a las 00:07

6 Respuestas

Codifica los productos comportamiento observable se ajusta a los requisitos por definición. Por ejemplo, printf("").

El acceso a la variable volátil también constituye formalmente un comportamiento observable, aunque no me sorprendería que algunos compiladores aún descartaran las variables volátiles "innecesarias".

Por esta razón, una llamada a una función de E/S parece ser el mejor candidato para mí.

Respondido 28 Jul 12, 01:07

No sabía que "volátil" podría usarse de esa manera; pensé que era solo para cosas que podrían modificarse en otro hilo, pero supongo que tiene sentido, aunque no estoy usando hilos aquí, el compilador no podría no se eso Intenté simplemente imprimir las variables (a través de printf o cout), pero el entorno en el que estoy no me da ninguna salida de consola. (Consola Xbox antigua) Probaré con volatile y veré si funciona. - Darrel Hoffmann

@Darrel Hoffman: Dijiste que necesitabas un código para poner un punto de interrupción. mi vacío printf sirve exactamente para ese propósito. No para imprimir nada, sino solo para puntos de interrupción. - Hormiga

Sí, obtienes un punto de interrupción, pero las variables no utilizadas aún están optimizadas, por lo que no ayuda mucho. Por supuesto, podría imprimir las variables (aunque nunca vería el resultado), pero la instrucción printf vacía por sí sola no es tan útil. - Darrel Hoffmann

¿Puedes redirigir stdout? Quiero decir, ¿no puedes usar fprintf(stderr, "my var = %d\n" , myVar); ? si puede abrir un archivo en algún lugar, fprintf-ing puede hacer el truco. o ya sabes, imprime el valor y rompe en la impresión, no debería optimizarse... - tiburón

Puede probar la palabra clave "volátil". Alguna introducción está en http://en.wikipedia.org/wiki/Volatile_variable .

En términos generales, la palabra clave volatile está destinada a evitar que el compilador aplique optimizaciones en el código que suponga que los valores de las variables no pueden cambiar "por sí solos".

Respondido 28 Jul 12, 00:07

¿Has probado

#pragma optimize("",off)

?

MSVS específico creo - http://msdn.microsoft.com/en-us/library/chh3fb0k(v=vs.80).aspx

Respondido 28 Jul 12, 00:07

No especifica su compilador, así que solo agregaré aquí que he estado usando el especificador volátil en cualquier variable que uso específicamente para la depuración. En mi compilador (Embarcadero RAD Studio C++ Builder) lo he estado usando durante un par de años y nunca se ha optimizado la variable. Tal vez no uses este compilador, pero si lo haces, puedo decir que volatile ciertamente siempre me ha funcionado.

Respondido 28 Jul 12, 01:07

Aquí hay un ejemplo de un truco que he usado:

#include <ctime>
#include <iostream>
int main() {
    std::cout << "before\n";
    if (std::time(NULL) == 0) {
        std::cout << "This should not appear\n";
    }
    std::cout << "after\n";
}

Los programas time() La llamada siempre debe devolver un valor positivo, pero el compilador no tiene forma de saberlo.

Respondido 28 Jul 12, 01:07

Si el único propósito de la variable es que se vea en un punto de interrupción con un depurador, puede hacer que la variable sea global. Podría, por ejemplo, mantener un búfer global:

#ifdef DEBUG
char dbg_buffer[512];
template <typename T>
void poke_dbg (const T &t) {
    memcpy(dbg_buffer, &t, sizeof(T));
}
#else
#define poke_dbg(x)
#endif

Luego, durante la depuración, puede inspeccionar el contenido de dbg_buffer (con una conversión adecuada si lo desea).

Respondido 28 Jul 12, 03:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.