The Dark Side of C++ Templates
Originally published: 2009-02-11
Last updated: 2009-02-11
One of the perceived drawbacks of Java's parameterized types is “type erasure”: the compiler does not preserve parameterization information in the bytecode. C++ templates, by comparison, generate code specific to each parameterization, with “mangled” method names to ensure that you only call methods appropriate to the concrete parameteriation. For example, consider this C++ template:
template<class T> class Foo
{
T value;
public:
Foo(T val) { value = val; }
T get() { return value; }
};
If you parameterize this template as Foo<int< and
Foo, the compiler creates distinct code for each.
You can disassemble this code on Linux using the objdump tool, and see the different names that are given to each parameterized
method:
Disassembly of section .text._ZN3FooIiE3getEv: 00000000 <Foo<int>::get()>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 08 mov 0x8(%ebp),%eax 6: 8b 00 mov (%eax),%eax 8: 5d pop %ebp 9: c3 ret Disassembly of section .text._ZN3FooIPiE3getEv: 00000000 <Foo<int*>::get()>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 08 mov 0x8(%ebp),%eax 6: 8b 00 mov (%eax),%eax 8: 5d pop %ebp 9: c3 ret
Hmm, that's the same code. Which makes sense, because on my platform a pointer
is the same size as an int. However, it means that the
following code compiles and runs without incident … although reversing
the assignment, so that the int parameterization is
treated as int*, fails rather spectacularly.
int main(int argc, char** argv)
{
int i = 12;
Foo<int*> f1 = Foo<int*>(&i);
Foo<int> *f2 = (Foo<int>*)&f1;
printf("%i %i\n", *(f1.get()), (*f2).get());
return (0);
}
C++, it turns out, has its own form of type erasure, known as the C-style pointer cast. And while nobody in their right mind would use a cast like the one shown here — except maybe as a typo — the ability does exist. Because, ultimately, strong typing is a myth. Once the code comes out of the compiler, it's just pushing bytes from one place to another.
Copyright © Keith D Gregory, all rights reserved