guia disponibilidad comandos clusvcadm cluster alta c++ virtual vtable

c++ - disponibilidad - comandos cluster linux



Dirección de impresión de la función miembro virtual (4)

Estoy tratando de imprimir la dirección de una función miembro virtual. Si sé qué clase implementa la función puedo escribir:

print("address: %p", &A::func);

Pero quiero hacer algo como esto:

A *b = new B(); printf("address: %p", &b->func); printf("address: %p", &b->A::func);

Sin embargo esto no se compila. ¿Es posible hacer algo como esto, tal vez buscar la dirección en vtable en tiempo de ejecución?


Actualmente no hay una forma estándar de hacer esto en C ++, aunque la información debe estar disponible en algún lugar. De lo contrario, ¿cómo podría el programa llamar a la función? Sin embargo, GCC proporciona una extensión que nos permite recuperar la dirección de una función virtual:

void (A::*mfp)() = &A::func; printf("address: %p", (void*)(b->*mfp));

... asumiendo que la función miembro tiene el prototipo void func() . Esto puede ser bastante útil cuando desea almacenar en caché la dirección de una función virtual o usarla en el código generado. GCC le advertirá sobre esta construcción a menos que especifique -Wno-pmf-conversions . Es poco probable que funcione con cualquier otro compilador.


Los punteros a las funciones miembro no siempre son direcciones de memoria simples. Vea la tabla en este artículo que muestra los tamaños de los punteros de función miembro en diferentes compiladores, algunos llegan hasta 20 bytes.

Como el artículo describe un puntero de función miembro, es en realidad un blob de datos definidos por la implementación para ayudar a resolver una llamada a través del puntero. Puede almacenarlos y llamarlos OK, pero si desea imprimirlos, ¿qué imprime? Es mejor tratarlo como una secuencia de bytes y obtener su longitud a través de sizeof .


No tiene mucho sentido para mí. Si tienes una función normal:

void f( int n ) { }

A continuación, puede tomar su dirección:

f

pero no puede tomar la dirección de una llamada de función, que es lo que parece querer hacer.


Por lo que puedo decir en el estándar, la única vez que obtiene un enlace dinámico es durante una llamada de función virtual. Y una vez que ha llamado a una función, está ejecutando las declaraciones dentro de la función (es decir, no puede "detenerse a medias" en la llamada y obtener la dirección).

Creo que es imposible.