Skip to content

QNX support: can_be_nullptr causes build failure with packages using create_service() #1742

@asobhy-qnx

Description

@asobhy-qnx

can_be_nullptr causes build failure with packages using create_service()

After commit 0750dc4, Rolling QNX build https://gitlab.com/qnx/ros2/ros2_qnx/-/jobs/1443549330 was broken due to the following error in examples_rclcpp_minimal_services:

Starting >>> examples_rclcpp_minimal_service
--- stderr: examples_rclcpp_minimal_service                             
In file included from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/service.hpp:28,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/callback_group.hpp:25,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/any_executable.hpp:20,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/memory_strategy.hpp:25,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/memory_strategies.hpp:18,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/executor_options.hpp:20,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/executor.hpp:37,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/executors/multi_threaded_executor.hpp:25,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/executors.hpp:21,
                 from /home/builder/ros2_rolling/install/aarch64le/include/rclcpp/rclcpp.hpp:155,
                 from /home/builder/ros2_rolling/src/ros2/examples/rclcpp/services/minimal_service/main.cpp:19:
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/any_service_callback.hpp: In instantiation of 'struct rclcpp::detail::can_be_nullptr<void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >), void>':
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/any_service_callback.hpp:104:80:   required by substitution of 'template<class CallbackT, typename std::__1::enable_if<rclcpp::detail::can_be_nullptr<CallbackT, void>::value, int>::type <anonymous> > void rclcpp::AnyServiceCallback<example_interfaces::srv::AddTwoInts>::set<CallbackT, <enumerator> >(CallbackT&&) [with CallbackT = void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >); typename std::__1::enable_if<rclcpp::detail::can_be_nullptr<CallbackT, void>::value, int>::type <anonymous> = <missing>]'
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/create_service.hpp:43:3:   required from 'typename rclcpp::Service<ServiceT>::SharedPtr rclcpp::create_service(std::__1::shared_ptr<rclcpp::node_interfaces::NodeBaseInterface>, std::__1::shared_ptr<rclcpp::node_interfaces::NodeServicesInterface>, const string&, CallbackT&&, const rmw_qos_profile_t&, rclcpp::CallbackGroup::SharedPtr) [with ServiceT = example_interfaces::srv::AddTwoInts; CallbackT = void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >); typename rclcpp::Service<ServiceT>::SharedPtr = std::__1::shared_ptr<rclcpp::Service<example_interfaces::srv::AddTwoInts> >; std::__1::string = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >; rmw_qos_profile_t = rmw_qos_profile_t; rclcpp::CallbackGroup::SharedPtr = std::__1::shared_ptr<rclcpp::CallbackGroup>]'
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/node_impl.hpp:147:53:   required from 'typename rclcpp::Service<ServiceT>::SharedPtr rclcpp::Node::create_service(const string&, CallbackT&&, const rmw_qos_profile_t&, rclcpp::CallbackGroup::SharedPtr) [with ServiceT = example_interfaces::srv::AddTwoInts; CallbackT = void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >); typename rclcpp::Service<ServiceT>::SharedPtr = std::__1::shared_ptr<rclcpp::Service<example_interfaces::srv::AddTwoInts> >; std::__1::string = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >; rmw_qos_profile_t = rmw_qos_profile_t; rclcpp::CallbackGroup::SharedPtr = std::__1::shared_ptr<rclcpp::CallbackGroup>]'
/home/builder/ros2_rolling/src/ros2/examples/rclcpp/services/minimal_service/main.cpp:40:82:   required from here
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/any_service_callback.hpp:44:74: error: assignment of read-only location 'std::__1::declval<void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >)>()'
     decltype(std::declval<T>() == nullptr), decltype(std::declval<T &>() = nullptr)>>
                                                      ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
/home/builder/ros2_rolling/install/aarch64le/include/rclcpp/any_service_callback.hpp:44:74: error: assignment of read-only location 'std::__1::declval<void (&)(std::__1::shared_ptr<rmw_request_id_t>, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Request_<std::__1::allocator<void> > >, std::__1::shared_ptr<example_interfaces::srv::AddTwoInts_Response_<std::__1::allocator<void> > >)>()'

It seems that the compiler is refusing to accept the assignment decltype(std::declval<T &>() = nullptr

QNX uses g++ v8.3.0 with LLVM libc++

After removing decltype(std::declval<T &>() = nullptr and using can_be_nullptr as below, building examples_rclcpp_minimal_service succeeds.

template<typename T>
struct can_be_nullptr<T, std::void_t<
    decltype(std::declval<T>() == nullptr)>>
  : std::true_type {};
}

Is it okay for QNX implementation to test only if the callback function is equal to nullptr?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions