slimming unused std::stringstream locale/facets for embedded use?

190 Views Asked by At

I'm currently building an application for a lowish-spec ARM Cortex M4 in C++, using arm-none-eabi-g++ with stdlibc++ statically linked.

Some parts of the code are currently using std::stringstream to construct a string for various purposes, and would be quite difficult to remove/refactor out of the codebase.

A fairly basic subset of the code with all stringstreams shimmed

(via a fakestream.h header something like:

namespace blah {
    class stringstream {
        stringstream() {}
        ~stringstream() {}
        std::string str() {
           return "dummy";
        }
        template<typename T>
        stringstream& operator<<(T val) {
           return *this;
        }
    };
}

Along with invocations changed to:

#include "fakestream.h"
using blah::stringstream;
...
stringstream ss; 
ss << ...

trims about 350kB of code from the application, vs using std::stringstream.

I realise that some amount of that code is indeed necessary, but when using bloaty to inspect the .elf generated, a lot of the space seems to be taken with functions such as:

     6.5%  20.0Ki    std::num_get<>::_M_extract_int<>()
     3.7%  11.3Ki    std::__cxx11::money_get<>::_M_extract<>()
     2.9%  8.97Ki    std::money_get<>::_M_extract<>()
     2.7%  8.24Ki    d_print_comp_inner
     2.3%  6.97Ki    _svfprintf_r
     2.1%  6.42Ki    _svfwprintf_r
     2.0%  6.11Ki    __strftime.isra.0
     2.0%  6.09Ki    __ssvfscanf_r
     1.8%  5.61Ki    __ssvfiscanf_r
     1.8%  5.54Ki    std::__cxx11::time_get<>::_M_extract_via_format()
     1.5%  4.65Ki    std::num_get<>::_M_extract_float()
     1.4%  4.29Ki    std::__cxx11::money_put<>::_M_insert<>()
     1.4%  4.24Ki    std::num_get<>::do_get()
     1.4%  4.17Ki    std::__moneypunct_cache<>::_M_cache()
     1.3%  3.96Ki    _strtod_l
     1.3%  3.89Ki    _vfiprintf_r
     1.3%  3.87Ki    std::time_get<>::_M_extract_via_format()
     1.2%  3.81Ki    _dtoa_r
     1.2%  3.64Ki    std::money_put<>::_M_insert<>()
     1.1%  3.53Ki    std::locale::_Impl::_Impl()
     1.1%  3.28Ki    std::__facet_shims::__moneypunct_fill_cache<>()
     1.1%  3.27Ki    _svfiprintf_r
     1.0%  3.21Ki    std::num_put<>::_M_insert_int<>()
     0.8%  2.54Ki    std::num_put<>::_M_insert_float<>()
     0.7%  2.11Ki    d_type
     0.6%  1.94Ki    std::__cxx11::time_get<>::_M_extract_name()

and I know for certain that I'm not using any money or time related classes/values for stringstream or anywhere else.

From what (little) I understand, there's potentially some locale-related indirection happening in ios or ios_base to allow these types to be formatted according to the active locale, but I have no need for any of that in this application.

Is it possible to somehow indicate that these features are unnecessary, and should be omitted from the final output?

Ideally it would be possible to just continue using std::stringstream directly, but replacing it with a proxy or similar as above (but that actually delegates the necessary functionality for formatting basic integer types, strings, and a few custom object overloads).

0

There are 0 best solutions below