Forcing inlining of lambda in MSVC C++
Asked Answered
I

1

13

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?

Infamous answered 30/12, 2020 at 15:44 Comment(0)
S
17

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

Sweitzer answered 30/12, 2020 at 15:49 Comment(5)
Wow! Thanks. Do you know if there is somewhere a list (URL) of all possible standard-like attributes of MSVC with this syntax [[msvc:...]]?Infamous
@Infamous Unfortunately I can't find anything like that.Sweitzer
Note that while this code compiles, the call isn't actually inlined (even in the godbolt link provided in this answer, you can see that the lambda is still a call: call int main(void)'::2'::<lambda_1>::operator()(void)const). This has been my experience when using Visual Studio 19 and 22 as well, unfortunately.Quicklime
While the call to the operator() may inline - if the MSVC compiler does not experience a fatal code-gen situation that is - the call to the lambda constructor DOES NOT HAVE TO inline. This is an issue in the latest MSVC at this time. The attribute is not being applied to anything else than operator() of the lambda, which is flawed!Tamishatamma
Msvc did it wrong. The standard syntax is [[attr-apply-to-variable]] auto f = [capture] [[attr-apply-to-operator()]] (parameters) { function body }.Shreve

© 2022 - 2024 — McMap. All rights reserved.