Esta pregunta no se trata del lenguaje C++ en sí mismo (es decir, no del estándar) sino de cómo llamar a un compilador para implementar esquemas alternativos para la función virtual.¿Esquemas alternativos para implementar vptr?
El esquema general para implementar funciones virtuales es usar un puntero a una tabla de punteros.
class Base {
private:
int m;
public:
virtual metha();
};
equivalentemente en, digamos, C sería algo así como
struct Base {
void (**vtable)();
int m;
}
el primer miembro es por lo general un puntero a una lista de funciones virtuales, etc. (un trozo de área de la memoria que la aplicación tiene sin control de). Y en la mayoría de los casos esto cuesta el tamaño de un puntero antes de considerar a los miembros, etc. Así que en un esquema de direccionamiento de 32 bits alrededor de 4 bytes, etc. Si creaste una lista de objetos polimórficos de 40k en tus aplicaciones, esto es alrededor de 40k x 4 bytes = 160k bytes antes de cualquier variable miembro, etc. También sé que esta es la implementación más rápida y común entre las compilaciones de C++.
Sé que esto es complicado por herencia múltiple (especialmente con clases virtuales en ellos, es decir, estructura de diamante, etc.).
Una manera alternativa de hacer lo mismo es tener la primera variable como un identificador de índice a una tabla de vptrs (equivalente en C como abajo)
struct Base {
char classid; // the classid here is an index into an array of vtables
int m;
}
Si el número total de clases en una aplicación es menos de 255 (incluidas todas las instancias de plantillas posibles, etc.), entonces una char es lo suficientemente buena como para contener un índice, lo que reduce el tamaño de todas las clases polimórficas en la aplicación (excluyo los problemas de alineación, etc.).
Mi pregunta es, ¿hay algún cambio en GNU C++, LLVM o cualquier otro compilador para hacer esto? o reducir el tamaño de los objetos polimórficos?
Editar: Entiendo acerca de los problemas de alineación señalados. También un punto adicional, si esto fuera en un sistema de 64 bits (suponiendo un vptr de 64bit) con cada miembro de objeto polimórfico que cuesta alrededor de 8 bytes, entonces el costo de vptr es el 50% de la memoria. Esto se relaciona principalmente con pequeños polimórficos creados en masa, por lo que me pregunto si este esquema es posible para al menos objetos virtuales específicos, si no toda la aplicación.
El miembro m probablemente todavía esté alineado en un límite DWORD, por lo que no ganaría nada. – Henrik
El problema con ese esquema probablemente sería uno de alineación. Aquí, la estructura Base en su segundo ejemplo no tomaría (generalmente) 5 bytes, ahorrándole 3 bytes por objeto. El m probablemente estaría alineado en un límite de 4 bytes de todos modos, por lo que tendría 3 bytes de espacio perdido –
Creo que este método de implementación de tabla virtual es casi universal. Ciertamente, nunca he encontrado otro método o ninguna opción en GCC o Visual C++ que controle cómo se implementó. –