2012-08-09 21 views
25

Estaba depurando algunos códigos C++ en GDB y descubrí que algunas llamadas utilizaban el denominado "puntero sintético". Buscar en Google no produjo ningún resultado significativo. Al buscar aquí en SO, la mayoría de las preguntas con "sintético" en su título se refieren a alguna característica de Java (incluso si me sugieren que "sintético", en este contexto, podría significar "algo generado artificialmente por el compilador").¿Qué es un puntero sintético?

Por ejemplo, mira esto traza inversa, tomó de una operación, realizada en el constructor de MyClass, más de un miembro de la clase llama m (este código ha sido compilado con -O2):

#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144 
144  m->lock(); 
gdb$ print this 
$1 = (MyClass * const) <synthetic pointer> 
gdb$ print *this 
$2 = <optimized out> 

El seguimiento de la pila por encima de indica claramente que this es un puntero a un objeto que se ha optimizado, pero ¿cómo es posible que se haya invocado un método (es decir, su constructor)? Mi suposición más natural es que, incluso si el objeto incluido (m) se utiliza activamente en el código, algunas optimizaciones le permiten al compilador decidir que el objeto adjunto (this) no es realmente necesario. Dado que el método call m->lock(), que no se puede optimizar, se debe emitir en alguna parte, el compilador crea un objeto "falso" (sintético?), Que no se encuentra en ningún lugar de la memoria, solo para ajustar m.

No tengo una sólida experiencia como compilador, así que no sé si esta conclusión realmente tiene sentido. ¿Podría alguien por favor arrojar algo de luz sobre esto?

Gracias.

Respuesta

12

Un compilador puede determinar si this está realmente desreferenciado (es decir, utilizando los detalles de CPU específicos, no las reglas generales de C++). Si un método no desreferencia en realidad this, no hay necesidad de tener una representación phyiscal disponible.

[editar] En los comentarios, jww mencionó otro caso. Un singleton tiene solo una copia, por lo que un compilador inteligente puede tratar a sus miembros como globales. Eso significa que la dirección de singleton->foo es solo la constante &singleton + offset(foo). Como resultado de esta optimización, los métodos singleton no necesitan desreferenciar this para obtener acceso a los miembros singleton, por lo que nuevamente se puede optimizar.

+0

Sí, mi objeto 'MyClass' fue construido, nunca referenciado y, algún tiempo después, destruido; las únicas operaciones importantes fueron los efectos secundarios del constructor/destructor (para el registro, es una implementación personalizada de un bloqueo de ámbito). Entonces este debe ser el caso. Gracias. –

+2

¿Es eso lo que realmente es un puntero sintético (cuando "esto" está optimizado)? Siento que esta respuesta se puede interpretar como una nota al margen que sí, que un objeto puede optimizarse si nunca se lo referencia, pero no que el "puntero sintético" sea el caso de que "esto" se optimice. Veo un puntero sintético en los rastros de la pila y no estoy seguro de cómo interpretar que no es el mensaje habitual de . –

+2

@JoeyCarson: Es todo un poco filosófico. Formalmente, los objetos existen o no existen. Después de que se haya ejecutado un optimizador, los objetos pueden existir parcialmente, en la medida necesaria para el programa de comportamiento observable. Depende del depurador falsificar objetos reales, y eso no es una ciencia. – MSalters

Cuestiones relacionadas