asio icon indicating copy to clipboard operation
asio copied to clipboard

Compilation error for endpoint types with custom sockaddr type

Open stertingen opened this issue 2 years ago • 0 comments

I'm writing a SocketCAN wrapper for ASIO.

Considering the following piece of code (also tested with latest standalone ASIO):

#include <linux/can.h>

#include <boost/asio.hpp>

namespace can {
class endpoint;

class raw {
   public:
    using endpoint = can::endpoint;
    using socket = boost::asio::basic_raw_socket<raw>;

    int family() const noexcept { return AF_CAN; }

    int type() const noexcept { return SOCK_RAW; }

    int protocol() const noexcept { return CAN_RAW; }
};

class endpoint {
   public:
    using protocol_type = raw;
    using data_type = ::sockaddr_can;

    endpoint() noexcept {
        data_.can_family = AF_CAN;
        data_.can_ifindex = 0;
    }

    protocol_type protocol() const noexcept { return protocol_type(); }

    const void *data() const noexcept { return &data_; }

    void *data() noexcept { return &data_; }

    std::size_t size() const noexcept { return sizeof(data_type); }

    void resize(const std::size_t s) {
        if (s != size())
            throw std::system_error(
                std::make_error_code(std::errc::invalid_argument));
    }

    std::size_t capacity() const noexcept { return sizeof(data_type); }

   private:
    data_type data_;
};
}  // namespace can

int main() {
    boost::asio::io_context ctx;
    can::raw::socket cansock(ctx, can::raw::endpoint());
    ctx.run();
}

The documentation says that an 'endpoint' class should return void * or const void * from data(): https://think-async.com/Asio/asio-1.22.1/doc/asio/reference/Endpoint.html

However, the socket implementation using my custom endpoint class does not seem to allow sockaddr types other than sockaddr.

I'm getting a compilation failure:

[main] Building folder: foo 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /code/foo/build --config Debug --target all -j 14 --
[build] Scanning dependencies of target foo
[build] [ 50%] Building CXX object CMakeFiles/foo.dir/main.cpp.o
[build] In file included from /code/foo/libs/asio/asio/include/asio/basic_socket.hpp:38,
[build]                  from /code/foo/libs/asio/asio/include/asio/basic_datagram_socket.hpp:20,
[build]                  from /code/foo/libs/asio/asio/include/asio.hpp:26,
[build]                  from /code/foo/main.cpp:8:
[build] /code/foo/libs/asio/asio/include/asio/detail/reactive_socket_service.hpp: In instantiation of ‘asio::error_code asio::detail::reactive_socket_service<Protocol>::bind(asio::detail::reactive_socket_service<Protocol>::implementation_type&, const endpoint_type&, asio::error_code&) [with Protocol = can::raw; asio::error_code = std::error_code; asio::detail::reactive_socket_service<Protocol>::endpoint_type = can::endpoint]’:
[build] /code/foo/libs/asio/asio/include/asio/basic_socket.hpp:241:29:   required from ‘asio::basic_socket<Protocol, Executor>::basic_socket(ExecutionContext&, const endpoint_type&, typename asio::constraint<std::is_convertible<ExecutionContext&, asio::execution_context&>::value>::type) [with ExecutionContext = asio::io_context; Protocol = can::raw; Executor = asio::any_io_executor; asio::basic_socket<Protocol, Executor>::endpoint_type = can::endpoint; typename asio::constraint<std::is_convertible<ExecutionContext&, asio::execution_context&>::value>::type = int]’
[build] /code/foo/libs/asio/asio/include/asio/basic_raw_socket.hpp:202:57:   required from ‘asio::basic_raw_socket<Protocol, Executor>::basic_raw_socket(ExecutionContext&, const endpoint_type&, typename asio::constraint<std::is_convertible<ExecutionContext&, asio::execution_context&>::value>::type) [with ExecutionContext = asio::io_context; Protocol = can::raw; Executor = asio::any_io_executor; asio::basic_raw_socket<Protocol, Executor>::endpoint_type = can::endpoint; typename asio::constraint<std::is_convertible<ExecutionContext&, asio::execution_context&>::value>::type = int]’
[build] /code/foo/main.cpp:22:75:   required from here
[build] /code/foo/libs/asio/asio/include/asio/detail/reactive_socket_service.hpp:158:49: error: invalid conversion from ‘const void*’ to ‘const socket_addr_type*’ {aka ‘const sockaddr*’} [-fpermissive]
[build]   158 |     socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
[build]       |                                    ~~~~~~~~~~~~~^~
[build]       |                                                 |
[build]       |                                                 const void*
[build] In file included from /code/foo/libs/asio/asio/include/asio/detail/socket_ops.hpp:380,
[build]                  from /code/foo/libs/asio/asio/include/asio/detail/socket_holder.hpp:20,
[build]                  from /code/foo/libs/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp:26,
[build]                  from /code/foo/libs/asio/asio/include/asio/detail/reactive_socket_service.hpp:31,
[build]                  from /code/foo/libs/asio/asio/include/asio/basic_socket.hpp:38,
[build]                  from /code/foo/libs/asio/asio/include/asio/basic_datagram_socket.hpp:20,
[build]                  from /code/foo/libs/asio/asio/include/asio.hpp:26,
[build]                  from /code/foo/main.cpp:8:
[build] /code/foo/libs/asio/asio/include/asio/detail/impl/socket_ops.ipp:280:49: note:   initializing argument 2 of ‘int asio::detail::socket_ops::bind(asio::detail::socket_type, const socket_addr_type*, std::size_t, asio::error_code&)’
[build]   280 | int bind(socket_type s, const socket_addr_type* addr,
[build]       |                         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~
[build] make[2]: *** [CMakeFiles/foo.dir/build.make:63: CMakeFiles/foo.dir/main.cpp.o] Error 1
[build] make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/foo.dir/all] Error 2
[build] make: *** [Makefile:106: all] Error 2
[build] Build finished with exit code 2

As the documentation states that a static_cast<> will be performed, either the implementation or the documentation should be fixed accordingly.

stertingen avatar Jul 04 '22 13:07 stertingen