3
votes

My project uses template metaprogramming heavily. Most of the action happens inside recursive templates which produce objects and functions with very long (mangled) symbol names.

Despite the build time being only ~30 sec, the resulting executable is about a megabyte, and it's mostly symbol names.

On Linux, adding a -s argument to GCC brings the size down to ~300 KiB, but a quick look with a text editor shows there are still a lot of cumbersome names in there. I can't find how to strip anything properly on OS X… will just write that off for now.

I suspect that the vtable entries for providing typeid(x).name() are taking up a big chunk. Removing all use of the typeid operator did not cause anything more to be stripped on Linux. I think that the default exception handler uses the facility to report the type of an uncaught exception.

How might I maximize strippage and minimize these kilobyte-sized symbols in my executable?

1
Last I checked g++ uses a string compare for runtime type equality because of some corner cases (e.g. dlopen) where the type_info structs cannot reliably be resolved to the same instances to be checked by identity (pointer compare). These structs cannot be stripped in case some future code (libraries/plugins/etc) need the type_info. I will double check the code and report back later if I remembered correctly.John5342
Programs (as opposed to libraries) are usually not mean for dlopening, though.R. Martinho Fernandes
@R.MartinhoFernandes: programs can potentially use dlopen to load a library and you end up with the exact same issue looking from the other side.David Rodríguez - dribeas
Well… is there a "bigger hammer" out there that can just get rid of this crud? dlopen is a significant use case to be sure but a lot of developers just don't want their symbols out in the wild.Potatoswatter
I don't even care about completely removing the type_info names, but could just replace them will null-terminated hashes or serial IDs to satisfy the string comparison for type equality construct. IMO the ABI is defective if it mandates that my symbols go into the binary. With all these recursive templates and lambdas, a single type name can recapitulate the entire program structure, which should be a secret.Potatoswatter

1 Answers

-2
votes

Just run the program strip on the final executable. If you want to be fancier, you can use some other tools to store the debug info separately, but for your stated purpose, just strip a.out is fine. Maybe use the --strip-all option--I haven't tried that myself to see if it differs from the default behavior.

If you really want to try disabling RTTI, well, it's gcc -fno-rtti. But that may break your program badly--only one way to find out I guess.