Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does captureless lambda inside template function have multiple binary implementations?

Tags:

c++

c++11

lambda

It is rather theoretical one, but my problem if lambda which is defined inside of template function, but not depend on type T nor captures anything, (so technically could be declared outside of template) is recognized and optimized out by compilers? By optimized I mean that two foo<int> and foo<double> will use same binary code of lam, so it is not duplicated. Maybe, are they required to do so by Standard? I've tried to analyse this, but only idea I came up with is try static variable inside, but it is not a miracle that lambdas for different types do not share same static variable.

// foo with helper lam which is captureless and not T-dependant
template<typename T>
int foo(T x)
{
    auto lam = [](int x) {std::cout << "foo" << std::endl;  return -x; };
    return lam(sizeof(x));
}

// foo with helper lam which is captureless and not T-dependant with static inside
template<typename T>
int foo_s(T x)
{
    auto lam = [](int x) {static int count = 0; std::cout << "foo_s " << count++ << std::endl; return -x; };
    return lam(sizeof(x));
}

int main()
{
    foo(12); // foo
    foo(12.0); // foo

    foo_s(12); // foo_s 0
    foo_s(12); // foo_s 1

    foo_s(12.0); // foo_s 0
    foo_s(12.0); // foo_s 1
    return 0;
}
like image 892
R2RT Avatar asked Aug 22 '17 19:08

R2RT


1 Answers

The type of those two identical lambdas is different. The operator() on it is not the same.

If you never store or otherwise interact with the type of the lambda (this includes storing it in a std::function), then the fact it is a different type is irrelevant. If you have no static locals or similar leakage of the non-identical-ness of operator() it is equally irrelevant.

In MSVC, aggressive comdat folding will prevent two identical functions from having distinct existence. This includes two function being forced to have the same address. The GOLD linker does something similar, but less aggressive.

In gcc and clang, barring certain operations, the as-if rule will permit them to discard redundant types and functions.

The standard places few restrictions on inefficient program code. Compilers are free to inject a base-one noop chains that describe the tab indenting of your source, or anything else equally insane like having multiple redundant lambda function bodies for no good reason.

like image 147
Yakk - Adam Nevraumont Avatar answered Sep 28 '22 14:09

Yakk - Adam Nevraumont