[Bug]: grpc does not compile with lts_2023_01_25 and Visual Studio 2022
Describe the issue
When compiling grpc 1.52.0 with Visual Studio 2022 (17.4.4) and C++20 compilation fails with:
[1/43] Building CXX object CMakeFiles\grpc.dir\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc.obj
FAILED: CMakeFiles/grpc.dir/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc.obj
C:\PROGRA~1\MICROS~4\2022\PROFES~1\VC\Tools\MSVC\1434~1.319\bin\Hostx64\x64\cl.exe /nologo /TP -DCARES_STATICLIB -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WIN32_WINNT=0x600 -D_WINSOCK_DEPRECATED_NO_WARNINGS -ID:\src\grpc\third_party\re2 -ID:\src\grpc\third_party\zlib -ID:\src\grpc\include -ID:\src\grpc -ID:\src\grpc\third_party\address_sorting\include -ID:\src\grpc\_build\third_party\re2 -ID:\src\grpc\third_party\boringssl-with-bazel\src\include -ID:\src\grpc\src\core\ext\upb-generated -ID:\src\grpc\src\core\ext\upbdefs-generated -ID:\src\grpc\third_party\upb -ID:\src\grpc\third_party\xxhash -ID:\src\grpc\_build\third_party\zlib -ID:\src\grpc\_build\third_party\cares\cares -ID:\src\grpc\third_party\cares\cares -ID:\src\grpc\third_party\cares\cares\include -ID:\src\grpc\third_party\abseil-cpp /DWIN32 /D_WINDOWS /W3 /GR /EHsc /wd4065 /wd4506 /wd4200 /wd4291 /wd4244 /wd4267 /wd4987 /wd4774 /wd4819 /wd4996 /wd4619 /wd4503 /utf-8 /MDd /Zi /Ob0 /Od /RTC1 -std:c++20 /showIncludes /FoCMakeFiles\grpc.dir\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc.obj /Fdgrpc.pdb /FS -c D:\src\grpc\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): error C2664: 'ReturnType absl::lts_20230125::internal_any_invocable::Impl<Sig>::ExtractInvoker::<lambda_1>::()::<lambda_1>::operator ()(absl::lts_20230125::internal_any_invocable::TypeErasedState *,T &&) noexcept(false) const': cannot convert argument 2 from 'T' to 'T &&'
with
[
ReturnType=void,
Sig=void (absl::lts_20230125::Status),
T=absl::lts_20230125::Status
]
and
[
T=absl::lts_20230125::Status
]
and
[
T=absl::lts_20230125::Status
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: You cannot bind an lvalue to an rvalue reference
Downgrading Abseil from lts_2023_01_25 to lts_2022_06_23 "fixes the problem. Also downgrading the C++ standard to C++ 17 fixes the compilation.
I'm unsure if the issue is one of the following:
- regression in Abseil
- wrong usage from grpc
- compiler bug in Visual Studio in C++ 20 mode (we witnessed plenty of those in the last months)
Thanks, Gregor
Steps to reproduce the problem
Install Visual Studio 2022 (17.4.4), CMake, Ninja, and NASM.
git clone https://github.com/grpc/grpc.git
cd grpc
git submodule update --init
mkdir _build
cd _build
cmake -GNinja -DCMAKE_CXX_STANDARD=20 -DCMAKE_ASM_NASM_COMPILER="C:/Program Files/NASM/nasm.exe" ..
ninja CMakeFiles\grpc.dir\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc.obj
What version of Abseil are you using?
lts_2023_01_25
What operating system and version are you using?
Windows 10
What compiler and version are you using?
Visual Studio 2022 (17.4.4)
What build system are you using?
CMake 3.25.2
Additional context
No response
Complete error:
[1/1] Building CXX object CMakeFiles\grpc.dir\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc.obj
FAILED: CMakeFiles/grpc.dir/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc.obj
C:\PROGRA~1\MICROS~4\2022\PROFES~1\VC\Tools\MSVC\1434~1.319\bin\Hostx64\x64\cl.exe /nologo /TP -DCARES_STATICLIB -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WIN32_WINNT=0x600 -D_WINSOCK_DEPRECATED_NO_WARNINGS -ID:\src\grpc\third_party\re2 -ID:\src\grpc\third_party\zlib -ID:\src\grpc\include -ID:\src\grpc -ID:\src\grpc\third_party\address_sorting\include -ID:\src\grpc\_build\third_party\re2 -ID:\src\grpc\third_party\boringssl-with-bazel\src\include -ID:\src\grpc\src\core\ext\upb-generated -ID:\src\grpc\src\core\ext\upbdefs-generated -ID:\src\grpc\third_party\upb -ID:\src\grpc\third_party\xxhash -ID:\src\grpc\_build\third_party\zlib -ID:\src\grpc\_build\third_party\cares\cares -ID:\src\grpc\third_party\cares\cares -ID:\src\grpc\third_party\cares\cares\include -ID:\src\grpc\third_party\abseil-cpp /DWIN32 /D_WINDOWS /W3 /GR /EHsc /wd4065 /wd4506 /wd4200 /wd4291 /wd4244 /wd4267 /wd4987 /wd4774 /wd4819 /wd4996 /wd4619 /wd4503 /utf-8 /MDd /Zi /Ob0 /Od /RTC1 -std:c++20 /showIncludes /FoCMakeFiles\grpc.dir\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc.obj /Fdgrpc.pdb /FS -c D:\src\grpc\src\core\lib\event_engine\posix_engine\event_poller_posix_default.cc
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): error C2664: 'ReturnType absl::lts_20230125::internal_any_invocable::Impl<Sig>::ExtractInvoker::<lambda_1>::()::<lambda_1>::operator ()(absl::lts_20230125::internal_any_invocable::TypeErasedState *,T &&) noexcept(false) const': cannot convert argument 2 from 'T' to 'T &&'
with
[
ReturnType=void,
Sig=void (absl::lts_20230125::Status),
T=absl::lts_20230125::Status
]
and
[
T=absl::lts_20230125::Status
]
and
[
T=absl::lts_20230125::Status
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: You cannot bind an lvalue to an rvalue reference
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: see declaration of 'absl::lts_20230125::internal_any_invocable::Impl<Sig>::ExtractInvoker::<lambda_1>::()::<lambda_1>::operator ()'
with
[
Sig=void (absl::lts_20230125::Status)
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: while trying to match the argument list '(absl::lts_20230125::internal_any_invocable::TypeErasedState *, T)'
with
[
T=absl::lts_20230125::Status
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: while compiling class template member function 'ReturnType (__cdecl *absl::lts_20230125::internal_any_invocable::Impl<Sig>::ExtractInvoker(void))(absl::lts_20230125::internal_any_invocable::TypeErasedState *,T &&) noexcept(false)'
with
[
ReturnType=void,
Sig=void (absl::lts_20230125::Status),
T=absl::lts_20230125::Status
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/internal/any_invocable.h(855): note: see reference to function template instantiation 'ReturnType (__cdecl *absl::lts_20230125::internal_any_invocable::Impl<Sig>::ExtractInvoker(void))(absl::lts_20230125::internal_any_invocable::TypeErasedState *,T &&) noexcept(false)' being compiled
with
[
ReturnType=void,
Sig=void (absl::lts_20230125::Status),
T=absl::lts_20230125::Status
]
D:\src\grpc\third_party\abseil-cpp\absl/functional/any_invocable.h(155): note: see reference to class template instantiation 'absl::lts_20230125::internal_any_invocable::Impl<Sig>' being compiled
with
[
Sig=void (absl::lts_20230125::Status)
]
D:\src\grpc\src/core/lib/event_engine/posix_engine/posix_engine_closure.h(72): note: see reference to class template instantiation 'absl::lts_20230125::AnyInvocable<void (absl::lts_20230125::Status)>' being compiled
ninja: build stopped: subcommand failed.
It boils down to:
#include <utility>
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
void foo() {
absl::Status status_;
absl::AnyInvocable<void(absl::Status)> cb_;
cb_(std::exchange(status_, absl::OkStatus()));
}
Reverting 73789eb0689071b0b02b00cb3daed9f224ff1a10 fixes the test case and grpc compilation
According to https://twitter.com/TartanLlama/status/1626167895238615040 this seems to be fixed on the MSVC 17.5 preview compiler.
I believe it was a c++20-mode compiler bug. Out-of-lining the innermost lambda in ExtractInvoker (as a static member function) works around the error. Probably -- but I have not tested this -- decaying the lambda to a function pointer by prefixing with unary + would be sufficient also.