I have build the GCC4.7.1 cross-toolchain for ARM (cortex-m3). Now I'm linking an executable from C/C++ code that surely doesn't use some certain STL classes (e.g. std::string
). Furthermore exceptions and RTTI are turned off.
Though when I'm looking to the target ELF (e.g. using nm), there's a lot of symbols (apparantly from the libstdc++) linked in I wouldn't expect to find there (e.g. std::exception
, std::ios_base
, etc.).
Why is this there, and how can I get rid of this stuff to reduce the .text
section size of my target?
A coworker gave me a tip to override some GCC specific stub function:
namespace __gnu_cxx
{
void __verbose_terminate_handler()
{
for (;;)
;
}
}
This alone reduced the code size about 20KB.
Are there more such stubs I can override?
UPDATE:
OK, I found one really stupid error that removed most of the stuff I was wondering about, when fixing it:
There was an #include <iostream>
statement left (though nothing called from there) in one of the source files. This will of course link in the static std::cin
, std::cout
and std::cerr
instances and all the stuff that comes along with these.
Removing the #include <iostream>
statement reduced the .text
segment about another > 100KB portion.
Nevertheless:
There's still the std::exception
and std::basic_string
stuff I'm wondering about:
Namespace summaries:
==============================================================================
Type Size Namespace
T 774 'std'
W 184 'std::string::_Rep'
W 268 'std'
W 472 'std::string'
Class summaries:
==============================================================================
Type Size Class
T 50 'std::error_category'
T 52 'std::type_info'
T 54 'std::bad_exception'
T 54 'std::exception'
T 68 'std::bad_alloc'
T 98 'std::length_error'
T 214 'std::logic_error'
W 268 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >'
There isn't really much code size used, just about several 100 bytes, so I could live with neglecting it, but would appreciate, if I can get rid of this also.
Since I'm explicitly using no exceptions I wonder why these are still instantiated when linking. Usage of exceptions or not can't be really determined at runtime?!?
The only remaining thing from the __gnu_cxx
namespace I have left now is
Type Size Class
T 58 '__gnu_cxx::recursive_init_error'
It's another exception class.
FINALLY:
I used some additional flags to configure the GCC4.7 cross build:
--enable-gold=yes
--enable-lto
--enable-cxx-flags='-fno-exceptions -ffunction-sections -fno-omit-frame-pointer'
The latter flags are used to compile the libstdc++ and are essentially the same as used for building the target code (which is a reasonable action anyway). Exception references where gone afterwards (including the __gnu_cxx::recursive_init_error
).
Last thing was, I found an unexpected use of std::string
in our codebase. After fixing that, the reference to std::basic_string<char, std::char_traits<char>, std::allocator<char> >
also disappeared.
So I'm happy with the result now, no more unnecessary, unexpected overhead from libstdc++, no reason not to use C++ in preference over C.