lenguaje - dev c++ ventajas y desventajas
¿Podemos ver la plantilla de código instanciado por el compilador de C++ (6)
¿Hay alguna manera de conocer el código instanciado del compilador para una función de plantilla o una clase en C ++?
Supongo que tengo la siguiente pieza de código
template < class T> T add(T a, T b){
return a+b;
}
ahora cuando llamo
add<int>(10,2);
Me gustaría saber la función que el compilador crea para la versión específica de int.
Estoy usando G ++, VC ++. Será útil si algunos me pueden ayudar a señalar las opciones del compilador para lograr esto.
Espero que la pregunta sea clara. Gracias por adelantado.
Clang ( https://clang.llvm.org/ ) puede imprimir bastante AST de plantilla instanciada:
Para tu ejemplo:
test.cpp
template < class T> T add(T a, T b){
return a+b;
}
void tmp() {
add<int>(10,2);
}
Comando para imprimir bonito AST:
$ clang++ -Xclang -ast-print -fsyntax-only test.cpp
Clang-5.0 de salida:
template <class T> T add(T a, T b) {
return a + b;
}
template<> int add<int>(int a, int b) {
return a + b;
}
void tmp() {
add<int>(10, 2);
}
Cuando el optimizador ha realizado sus acciones, lo más probable es que no le quede nada que se parezca a una llamada a función. En su ejemplo específico, definitivamente terminará con una adición en línea, en el peor. Aparte de eso, siempre puedes emitir el ensamblador generado en un archivo separado durante la compilación, y ahí radica tu respuesta.
Definitivamente puede ver el código de ensamblado generado por el g ++ usando la opción "-S".
No creo que sea posible mostrar el código de plantilla equivalente "C ++", pero aún quisiera que un desarrollador de g ++ responda por qué. No conozco la arquitectura de gcc.
Al usar ensamblaje, puede revisar el código resultante buscando lo que se parece a su función. Como resultado de ejecutar gcc -S-O1 {yourcode.cpp}, obtuve esto (AMD64, gcc 4.4.4)
_Z3addIiET_S0_S0_:
.LFB2:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
leal (%rsi,%rdi), %eax
ret
.cfi_endproc
Que realmente es solo una adición int (leal).
Ahora, ¿cómo decodificar el creador de nombres de c ++? hay una utilidad llamada c ++ filt, se pega el nombre canónico (C-equivalente) y se obtiene el equivalente demandado de c ++
qdot@nightfly /dev/shm $ c++filt
_Z3addIiET_S0_S0_
int add<int>(int, int)
Lo más fácil es inspeccionar el ensamblaje generado. Puede obtener una fuente de ensamblaje utilizando la bandera -S para g ++.
Si buscas el código C ++ equivalente, entonces no. El compilador nunca lo genera. Es mucho más rápido para el compilador generar su representación intermedia directamente que generar primero c ++.
Si desea ver la salida del conjunto, use esto:
g++ -S file.cpp
Si desea ver algún (pseudo) código de C ++ que genera GCC, puede usar esto:
g++ -fdump-tree-original file.cpp
Para su función de add
, esto dará como resultado algo así como
;; Function T add(const T&, const T&) [with T = int] (null)
;; enabled by -tree-original
return <retval> = (int) *l + (int) *r;
(Pasé los parámetros por referencia para hacer que la salida sea un poco más interesante)