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
[...] 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With