uNetworking / uWebSockets

Simple, secure & standards compliant web server for the most demanding of applications
Apache License 2.0
17.24k stars 1.75k forks source link

C3493 error in WebSocketContextData.h #1225

Closed Phantomouse closed 3 years ago

Phantomouse commented 3 years ago

Hi there!

I'm using Visual Studio Community 2019 on Windows 10, /std:c++latest. uWebSockets version 19.0.0a5. uSockets version 0.7.1.

Having the following code (worked fine with uWebSockets v.18.14.0):

auto wsapp = uWS::App();
struct WSD {};
uWS::App().ws<WSD>("/*", {})
        .ws<WSD>("/pipe", {
            .idleTimeout = 0,
            .open = [](auto* ws) {
                cout << "Client connected to WSS channel" << endl;
            },
            .message = [](auto* ws, std::string_view message, uWS::OpCode opCode) {
                cout << "MSG: " << message << endl;
            },
            .close = [](auto* ws, int code, std::string_view message) {
                cout << "Client disconnected from WSS channel" << endl;
            }
        })
        .listen(9001, [](auto* lsock) {})
        .run();

After updating uWebSockets to 19.0.0a5 I've encountering error C3493 "failed" cannot be implicitly captured because no default capture mode has been specified" in 178 line of WebSocketContextData.h.

/* Note: this assumes we are not corked, as corking will swallow things and fail later on */
auto [written, failed] = asyncSocket->write(selectedData.data(), (int) selectedData.length());
/* If we want strict check for success, we can ignore this check if corked and repeat below
* when uncorking - however this is too strict as we really care about PROGRESS rather than
* ENTIRE SUCCESS - we need minor API changes to support correct checks */
if (!failed) { // <=== LINE 178
  if (this->resetIdleTimeoutOnSend) {
    auto *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) asyncSocket);
    webSocketData->hasTimedOut = false;
    asyncSocket->timeout(this->idleTimeoutComponents.first);
  }
}

Switching compiler to /std:c++17 standard is fixing the problem, but causing another error in line 5 of my code (.idleTimeout = 0, and so on): error C7555: use of designated initializers requires at least '/std:c++latest'

What am I doing wrong? Is it misconfiguration of my compiler or I just can't use std:c++latest with uWebSockets?

ghost commented 3 years ago

Hello,

It being an alpha means I haven't looked at Windows whatsoever so it can just be a mistake on my end that will be fixed in later releases. I really only focus on macOS and Linux when developing.

Phantomouse commented 3 years ago

That's a pity. I like your library, but sometimes I need to use it under Windows. I've made a little changes to fix it in my local environment, but it will be great if you'' return to my issue when you'll have more time.

auto res = asyncSocket->write(selectedData.data(), (int) selectedData.length());
if (!res.second) { // <=== LINE 178
  if (this->resetIdleTimeoutOnSend) {
    auto *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) asyncSocket);
    webSocketData->hasTimedOut = false;
    asyncSocket->timeout(this->idleTimeoutComponents.first);
  }
}
ghost commented 3 years ago

It works on Windows - just maybe not right now in alpha stage

ghost commented 3 years ago

I can reproduce this with Visual Studio 16.9.3.

However, this is a bug in Microsoft's crappy compiler. It works in C++17 mode (but then you can't use designated initializers).

https://en.cppreference.com/w/cpp/language/structured_binding

This is structured binding, they broke it in their latest preview. This is not a bug here, it is Microsoft's failure to create anything close to a competent compiler. Visual Studio has always been the Internet Explorer of development tools - it sucks. I don't care.

Use clang instead, they support it. Then you get a compiler that doesn't eat ass.