Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing inlining of lambda in MSVC C++

Next code compiles in CLang/GCC, and successfully inlines lambda:

Try it online!

#include <iostream>

int main() {
    int x = 0;
    auto f = [&]() __attribute__((always_inline)) {
        ++x;
    };
    f();
    std::cout << x;
}

But similar code with __forceinline in latest MSVC (2019 v16.8.3) doesn't compile, although was announced as implemented in v16.7:

Try it online!

#include <iostream>

int main() {
    int x = 0;
    auto f = [&]() __forceinline {
        ++x;
    };
    f();
    std::cout << x;
}

throwing compile error 0305.cpp(5): error C3260: 'type': skipping unexpected token(s) before lambda body.

Is it really not yet implemented or am I using __forceinline in a wrong place? Is there any other way to force inlining of lambda in MSVC?

Also is there any way in all of popular compilers (e.g. CLang/GCC/MSVC) to not compile code (and throw compiling error) in case if given lambda was used in some place without being inlined? Also does __attribute__((always_inline)) and __forceinline in all 100% of use cases guarantee that lambda is definitely inlined?

like image 309
Arty Avatar asked Dec 30 '20 15:12

Arty


People also ask

Why don't we have lambda expressions in C++?

Modern C++ has lambda expressions. However, in C you have to define a function by name and pass a pointer — not a huge problem, but it can get messy if you have a lot of callback functions that you use only one time. It’s just hard to think up that many disposable function names.

How to capture external variables from enclosing scope in lambda expression?

A lambda expression can have more power than an ordinary function by having access to variables from the enclosing scope. We can capture external variables from enclosing scope by three ways : A lambda with empty capture clause [ ] can access only those variable which are local to it.

How do you initialize a variable in a lambda function?

In C++14, you can introduce and initialize new variables in the capture clause, without the need to have those variables exist in the lambda function’s enclosing scope. The initialization can be expressed as any arbitrary expression; the type of the new variable is deduced from the type produced by the expression.

What is a Lambda declarator in C++?

A parameter list ( lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. In C++14, if the parameter type is generic, you can use the auto keyword as the type specifier. This keyword tells the compiler to create the function call operator as a template.


1 Answers

Per Jonathan Caves reply on the feature request, the supported syntax going forward is

auto f = [&]() [[msvc::forceinline]] {
    ++x;
};

which does compile

It looks like they wanted it to comply with the attributes syntax that was introduced in C++11

like image 157
NathanOliver Avatar answered Sep 21 '22 02:09

NathanOliver