undefined reference to `std::errc::operation_canceled` when compiling websocketpp example code with mingw

不打扰是莪最后的温柔 提交于 2019-12-14 02:48:38

问题


I'm trying to use websocketpp to write a cross-platform program that communicates using websockets. I would like to use the asio-based transport layer.

My understanding was that if I am using C++11, I can configure asio to stand-alone from boost and use std::thread, and that websocketpp is similarly header-only under such circumstances.

However, when I actually try to compile any of the websocketpp tutorials this way, such as the tutorials/utility_client, it works fine on g++ and clang, but I get strange compilation errors on mingw:

In file included from websocketpp-0.6.0/include/websocketpp/config/asio_no_tls_client.hpp:32:0,
                 from main.cpp:7:
websocketpp-0.6.0/include/websocketpp/transport/asio/endpoint.hpp: In member function ‘void websocketpp::transport::asio::endpoint<config>::handle_accept(websocketpp::transport::accept_handler, const error_code&)’:
websocketpp-0.6.0/include/websocketpp/transport/asio/endpoint.hpp:764:28: error: ‘operation_canceled’ is not a member of ‘std::errc’
             if (asio_ec == lib::asio::errc::operation_canceled) {
                            ^

I'm scratching my head as to what this means and how to fix this. This doesn't appear to be related to the lack of boost -- std::errc::operation_canceled appears to be a well-defined C++11 symbol according to this, not always accurate, website. Does this mean my toolchain is broken / defective? I tried installing a different version of the mingw toolchain and it had the same problem.

I couldn't find any references to anyone having similar problems with this symbol not being found, so maybe I'm configuring the library wrong? Here is my compilation line:

"$CXX" -std=c++11 -Iasio-1.10.6/include -Iwebsocketpp-0.6.0/include -D_WEBSOCKETPP_CPP11_THREAD_=1 -DASIO_STANDALONE=1 main.cpp -lpthread

I made a repository to assist in reproducing my exact setup, but there's not much going on here -- I downloaded both libs from most recent releases from their respective repos. Since compilation dies in one of the includes the body of main.cpp seems not terribly relevant, but I am just using their tutorial code.

If anyone could throw me a line on this I would greatly appreciate it. :)

Edit: I am not really sure but I have reported this as a bug at mingw-w64: http://sourceforge.net/p/mingw-w64/support-requests/105/


回答1:


I have reported this as a bug at mingw-w64

The mingw-w64 compiler is C++11 non-compliant in not defining this error-code, but the folks already know that and it's deliberate. (Although offhand I don't know why they couldn't fix it.)

The relevant header file is:

<toochain_dir>/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/error_constants.h

and here is the definition of enum class std::errc:

// Most of the commented-out error codes are socket-related and could be
// replaced by Winsock WSA-prefixed equivalents.
  enum class errc
    {
//    address_family_not_supported =        EAFNOSUPPORT,
//    address_in_use =              EADDRINUSE,
//    address_not_available =           EADDRNOTAVAIL,
//    already_connected =           EISCONN,
      argument_list_too_long =          E2BIG,
      argument_out_of_domain =          EDOM,
      bad_address =                 EFAULT,
      bad_file_descriptor =             EBADF,
//    bad_message =                 EBADMSG,
      broken_pipe =                 EPIPE,
//    connection_aborted =          ECONNABORTED,
//    connection_already_in_progress =      EALREADY,
//    connection_refused =          ECONNREFUSED,
//    connection_reset =            ECONNRESET,
//    cross_device_link =           EXDEV,
//    destination_address_required =        EDESTADDRREQ,
      device_or_resource_busy =         EBUSY,
      directory_not_empty =             ENOTEMPTY,
      executable_format_error =         ENOEXEC,
      file_exists =                     EEXIST,
      file_too_large =              EFBIG,
      filename_too_long =           ENAMETOOLONG,
      function_not_supported =          ENOSYS,
//    host_unreachable =            EHOSTUNREACH,
//    identifier_removed =          EIDRM,
      illegal_byte_sequence =           EILSEQ,
      inappropriate_io_control_operation =  ENOTTY,
      interrupted =                 EINTR,
      invalid_argument =            EINVAL,
      invalid_seek =                ESPIPE,
      io_error =                EIO,
      is_a_directory =              EISDIR,
//    message_size =                EMSGSIZE,
//    network_down =                ENETDOWN,
//    network_reset =               ENETRESET,
//    network_unreachable =             ENETUNREACH,
//    no_buffer_space =             ENOBUFS,
#ifdef _GLIBCXX_HAVE_ECHILD
      no_child_process =            ECHILD,
#endif
//    no_link =                 ENOLINK,
      no_lock_available =           ENOLCK,
//    no_message_available =            ENODATA,
//    no_message =              ENOMSG,
//    no_protocol_option =          ENOPROTOOPT,
#ifdef _GLIBCXX_HAVE_ENOSPC
      no_space_on_device =          ENOSPC,
#endif
//    no_stream_resources =             ENOSR,
      no_such_device_or_address =       ENXIO,
      no_such_device =              ENODEV,
      no_such_file_or_directory =       ENOENT,
      no_such_process =             ESRCH,
      not_a_directory =             ENOTDIR,
//    not_a_socket =                ENOTSOCK,
//    not_a_stream =                ENOSTR,
//    not_connected =               ENOTCONN,
      not_enough_memory =           ENOMEM,
#ifdef _GLIBCXX_HAVE_ENOTSUP
      not_supported =               ENOTSUP,
#endif
//    operation_canceled =          ECANCELED,
//    operation_in_progress =           EINPROGRESS,
#ifdef _GLIBCXX_HAVE_EPERM
      operation_not_permitted =         EPERM,
#endif
//    operation_not_supported =         EOPNOTSUPP,
#ifdef _GLIBCXX_HAVE_EWOULDBLOCK
      operation_would_block =           EWOULDBLOCK,
#endif
//    owner_dead =              EOWNERDEAD,
      permission_denied =           EACCES,
//    protocol_error =              EPROTO,
//    protocol_not_supported =          EPROTONOSUPPORT,
      read_only_file_system =           EROFS,
      resource_deadlock_would_occur =       EDEADLK,
      resource_unavailable_try_again =      EAGAIN,
      result_out_of_range =             ERANGE,
//    state_not_recoverable =           ENOTRECOVERABLE,
//    stream_timeout =              ETIME,
//    text_file_busy =              ETXTBSY,
#ifdef _GLIBCXX_HAVE_ETIMEDOUT
      timed_out =               ETIMEDOUT,
#endif
      too_many_files_open_in_system =       ENFILE,
      too_many_files_open =             EMFILE,
      too_many_links =              EMLINK
//    too_many_symbolic_link_levels =       ELOOP,
#ifdef _GLIBCXX_HAVE_EOVERFLOW
    ,
      value_too_large =             EOVERFLOW
#endif
//    wrong_protocol_type =             EPROTOTYPE
   };

You see that operation_canceled is one of those commented out.

As suggested there, you will need to use the winsock error code WSAECANCELLED, defined in winerror.h. If you want portability, of course you'll need to make this use rather than std::errc::operation_canceled conditional upon compiletime determination of the host OS.



来源:https://stackoverflow.com/questions/33662788/undefined-reference-to-stderrcoperation-canceled-when-compiling-websocketp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!