QNX support: can_be_nullptr causes build failure with packages using create_service()
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 805
- Forks
- 564
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 27
Description
can_be_nullptr causes build failure with packages using create_service()
After commit ros2/rclcpp@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?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue points to rclcpp/any_service_callback.hpp and the call chain through create_service(); start by inspecting can_be_nullptr and the failing instantiation from examples/rclcpp/services/minimal_service/main.cpp. Reproduce the QNX/libc++ build failure, determine the accepted nullability check, and confirm examples_rclcpp_minimal_service builds successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100