Search code examples
c++c++11templateslambdageneric-lambda

Generic lambdas and binary size / code bloat


What is the difference in the resulting binary, when we compare this code:

struct S {
    template<typename... Args>
    void operator()(Args... args) { /* ... */ }
};

// And then inside some block:
S s;
s(42);
s(3.14, "Hi!");
s("Hi!", 3.14);

...to this code:

const auto l = [](auto... args) { /* ... */ };

// And then inside some block:
l(42);
l(3.14, "Hi!");
l("Hi!", 3.14);

As far as I understand, the struct code creates 3 template instantiations for operator(), all of which appear as symbols in the binary. What about the lambda? The compiler creates an object similar to s. But if it's an unnamed class type, does it create symbols in the binary?

Motivation: I've used a template-heavy library where I had to enable /bigobj. I would like to avoid that and I'm wondering if lambdas can help against template code bloat. Is this defined in the standard, or dependent on compiler implementation?


Solution

  • I think, unfortunately, lambda can't help you solve the problem of code bloat. For your example, like struct S, The compiler will also create three different operator () for lambda.

    In order to prove my point of view, I compiled the following program with g++ 8.1.0 on Linux.

    int main()
    {
        const auto l = [](auto... args) { /* ... */ };
        l(42);
        l(3.14, "Hi!");
        l("Hi!", 3.14);
    }
    

    and then use the nm command to view the binary file, the result is as follows:

    output of nm command

    It is not difficult to see that the last three lines are the symbols of the three operator (). So, in this case, lambda and struct S are not fundamentally different.