Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Inline lambda argument

Tags:

c++

lambda

inline

Consider the followng code

#include <iostream>
#include <functional>

using namespace std;

inline void readandrun(function<void(int)> callback) {
    int i;
    i = 1;
    callback(i);
}

int main(int argc, char *argv[])
{
#ifdef LAMBDA
    readandrun([](int i){ printf("the read number is: %d\n",i);});
#else
    int i;
    i = 1;
    printf("the read number is: %d\n",i);
#endif
    return 0;
}

Compiling with

g++ -DLAMBDA -O2 -std=c++17 -S test.cpp -o test_long.S 

Yields code involving jumps while

g++ -O2 -std=c++17 -S test.cpp -o test_short.S 

Does not. Which kind of makes sense but is it possible to tell the compiler to inline the lambda argument since it's known at compile time? I would be willing to switch compilers but for completeness:

$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
like image 647
fakedrake Avatar asked Dec 07 '22 10:12

fakedrake


1 Answers

[...] is it possible to tell the compiler to inline the lambda argument since it's known at compile time?

Highly unlikely (in other words - no), which is mainly because you use std::function which, due to it's implementation's nature, uses type erasure and achieves this with dynamic allocation. When you call it, a virtual call is made so there is a jump. In order to inline the code, you may switch to:

template <typename Callback>
inline void readandrun(Callback callback) {
    int i;
    i = 1;
    callback(i);
}

That way, the lambda's exact type is deduced and the code is perfectly fine for inlineability.


Remember - lambda's type is never std::function. It's (the std::function) merely a wrapper around a callable with actual type erased.

like image 54
Fureeish Avatar answered Dec 30 '22 05:12

Fureeish