[cfe-dev] Binary size when using std::function with lambda expression

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Fri Jan 8 17:27:57 PST 2021


On Fri, Jan 8, 2021 at 5:45 AM Cyril Makloufi via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> When using std::function instead of function pointer (see the sample of
> code) on Mac, we get a huge difference between size of generated binary
> (80ko when using function pointer and 157ko whit std::function).
>
This is expected. std::function<void()> is a library type. It does "type
erasure," a C++ technique which you can learn about here:
https://www.youtube.com/watch?v=tbUCHifyT24 ("Back to Basics: Type
Erasure", CppCon 2019)
Contrast with core-language lambda expressions:
https://www.youtube.com/watch?v=3jCOwajNch0 ("Back to Basics: Lambdas from
Scratch", CppCon 2019)

You can do a lot of things with `std::function<void()> f` that you can't do
with `void (*f)()`; for example, `std::function<void()> f` can hold a copy
of a lambda which itself has captures.

    int i = 42;
    std::function<void()> f = [&]() { std::cout << i; };  // OK
    void (*g)() = [&]() { std::cout << i; };  // Ill-formed

You pay for this flexibility in code size (and speed) (and, in many cases,
heap-allocations).

Additionally, std::function is notoriously inefficient *even as type-erased
types go*. This is partly because the paper standard requires it to do so
much (e.g. the .target_type() method); and partly because its
implementation was done ~15 years ago and maybe we'd like to apply some
lessons learned since then, but that would break ABI.
https://quuxplusone.github.io/blog/2019/01/06/hyper-function/

HTH,
Arthur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210108/89f71959/attachment.html>


More information about the cfe-dev mailing list