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