10

Dado un metaprograma de plantilla (TMP), ¿los compiladores de C++ producen estadísticas de compilación que cuentan el número de clases instanciadas? ¿O hay alguna otra manera de obtener este número automáticamente? Entonces, por ejemplo, la obiquitous factorial¿Cuenta automáticamente el número de clases instanciadas en un TMP?

#include <iostream> 

template<int N> struct fact { enum { value = N * fact<N-1>::value }; }; 
template<> struct fact<1> { enum { value = 1 }; }; 

int main() 
{ 
    const int x = fact<3>::value; 
    std::cout << x << "\n"; 
    return 0; 
} 

me gustaría volver el número 3 (ya hecho < 3>, hecho < 2>, y el hecho de < 1> se crean instancias). Este ejemplo, por supuesto, es trivial, pero cada vez que empiece a usar, p. Boost.MPL, los tiempos de compilación realmente explotan, y me gustaría saber cuánto de eso se debe a instancias de clases ocultas. Mi pregunta es principalmente para Visual C++, pero las respuestas para gcc también serían apreciadas.

EDITAR: mi enfoque muy frágil actual de Visual C++ está agregando el interruptor de compilación de una de Stephan T. Lavavej videos/d1reportAllClassLayout y haciendo un grep + número de palabras en el archivo de salida, pero (a) aumenta compilar veces enormemente y (b) la expresión regular es difícil de obtener el 100% de lo correcto.

Respuesta

7

Hice un one-line change a GCC que lo hace imprimir el nombre de cada plantilla de clase a medida que lo crea. Ya puede llamar al front-end de C++ cc1plus directamente sin el indicador -quiet para obtener lo mismo para las plantillas de funciones.

No he conseguido convertir eso en una opción de GCC adecuada todavía, es solo un truco en mi propio árbol fuente. Estoy pensando en implementarlo como un complemento, pero no está cerca de la parte superior de mi lista de cosas por hacer.

+0

+1. Sugerí que debería ser bastante fácil piratear cualquier compilador de código abierto, pero en realidad lo probaste de la mejor manera posible (escribiendo un parche que realmente lo haga). – abarnert

+0

¡Gracias! Lo que sería incluso más conveniente (¡sí, el aumento de alcance se acerca!) Es un registro de todas las plantillas de clase y el número de instancias, en lugar de solo el número total o la lista completa de todas las instancias. Tal vez un script de Perl para postprocesar el registro de compilación completo es lo que debería intentar. – TemplateRex

+1

simplemente canalice la salida a 'awk -F '<' '{templates [$ 1] ++} END {para (t en plantillas) print t, templates [t]}' –

2

No hay, por supuesto, una forma portátil de hacerlo.

Hay formas chulas de hacerlo para la mayoría de los compiladores. Ya encontraste uno para MSVC. Para gcc, probablemente puedas usar gccxml. O bien, para cualquier compilador de código abierto (gcc o clang), debería ser bastante simple agregar código en el momento de la creación de instancias, ya sea que mantenga el conteo o registre algo que pueda filtrar después de completar la compilación.

Para Clang/LLVM, puede simplemente crear un complemento que enganche la creación de instancias, que es mucho más limpio, pero probablemente realmente más trabajo.

Una compilación con símbolos de depuración, sin optimización y sin stripping podría terminar con los nombres destrozados de cada creación de instancias, que puede grep. Sin embargo, algunos compiladores (incluido gcc) siempre alinearán al menos algunos métodos, ya sea que los quiera o no. Si usted está dispuesto a modificar su código, es probable que pueda forzarlo para generar instancias fuera de línea, tal vez algo como esto:

template<int N> struct fact { 
    enum { value = N * fact<N-1>::value }; 
    int *dummy() { return &fact<N-1>::value; } 
}; 
+0

¡Gracias!La modificación del código no es realmente una opción porque el 99% de las plantillas de clase instanciadas son de Boost.MPL y , etc., y quiero tener un recuento limpio de ellas también. – TemplateRex

+0

Creo que MSVC se puede configurar para desactivar absolutamente toda la alineación y la optimización, lo que significa que obtendrá una instanciación fuera de línea para todo, pero no creo que ningún otro compilador tenga esa configuración. – abarnert

1

No es una herramienta escrita por Steven Watanabe que se puede utilizar para contar el número de instancias de plantilla. Puede obtenerlo here. Básicamente, modifica el código para que se genere una advertencia del compilador cada vez que se crea una instancia de una clase y luego puede procesar el texto resultante con expresiones regulares, por ejemplo.

+0

Gracias, probaría eso. – TemplateRex

Cuestiones relacionadas