Can we see the template instantiated code by C++ compiler
Now there is an on-line tool which does this for you: https://cppinsights.io/ For example, this code
template<class X, class Y> auto add(X x, Y y) {
return x + y;
}
int main()
{
return add(10, 2.5);
}
Is translated to
template<class X, class Y> auto add(X x, Y y) {
return x + y;
}
/* First instantiated from: insights.cpp:9 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
double add<int, double>(int x, double y)
{
return static_cast<double>(x) + y;
}
#endif
int main()
{
return static_cast<int>(add(10, 2.5));
}
Clang (https://clang.llvm.org/) can pretty-print AST of instantiated template:
For your example:
test.cpp
template < class T> T add(T a, T b){
return a+b;
}
void tmp() {
add<int>(10,2);
}
Command to pretty-print AST:
$ clang++ -Xclang -ast-print -fsyntax-only test.cpp
Clang-5.0 output:
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);
}
You can definitely see the assembly code generated by the g++ using the "-S" option.
I don't think it is possible to display the "C++" equivalent template code - but I would still want a g++ developer to chime in why - I don't know the architecture of gcc.
When using assembly, you can review the resulting code looking for what resembles your function. As a result of running gcc -S -O1 {yourcode.cpp}, I got this (AMD64, gcc 4.4.4)
_Z3addIiET_S0_S0_:
.LFB2:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
leal (%rsi,%rdi), %eax
ret
.cfi_endproc
Which really is just an int addition (leal).
Now, how to decode the c++ name mangler? there is a utility called c++filt, you paste the canonical (C-equivalent) name and you get the demangled c++ equivalent
qdot@nightfly /dev/shm $ c++filt
_Z3addIiET_S0_S0_
int add<int>(int, int)
If you want to see the assembly output, use this:
g++ -S file.cpp
If you want to see some (pseudo) C++ code that GCC generates, you can use this:
g++ -fdump-tree-original file.cpp
For your add
function, this will output something like
;; Function T add(const T&, const T&) [with T = int] (null)
;; enabled by -tree-original
return <retval> = (int) *l + (int) *r;
(I passed the parameters by reference to make the output a little more interesting)