ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A
Ask Your Question

Why is everything a shared_ptr in ROS2?

asked 2020-10-09 07:48:53 -0600

nnmm gravatar image

updated 2020-10-09 08:05:12 -0600

Many functions in rclcpp return a std::shared_ptr, e.g. create_subscription(), or take a std::shared_ptr argument, e.g. subscriber callbacks. This surprises me because it's my impression that it's good practice to use shared pointers only when needed, and prefer a unique_ptr or even plain objects.

For instance, the std::shared_ptr returned by create_subscription() appears to be the sole owner of the subscriber, so it could be a std::unique_ptr instead. Besides being a bit more performant and flexible, this would also serve as documentation: I had to write a test case to find out that there is only one owner and that you can therefore shut down a subscription by resetting it to nullptr, but if it had been a std::unique_ptr, that would have been obvious. Similarly, everywhere a pointer is used, it theoretically allows for a nullptr, but if a function returned a plain object or accepted arguments by reference instead, users of the API could rely on the object never being null.

I'm not sure if plain objects would be possible – maybe rclcpp uses polymorphism and SubscriptionT is only a base class, while the true type is hard/impossible to name?

So why is everything a shared pointer in ROS2? I hope a broad question like makes sense, but if not, my main questions would be:

  • Why are there no versions of create_subscription() and create_publisher() that return unique pointers or plain objects?
  • Why do the subscription callbacks not receive messages by reference?
edit retag flag offensive close merge delete


I'd also be interested in some discussion surrounding this. It's also easy to convert a unique_ptr to a shared_ptr if shared ownership is needed during runtime. My guess is that it's done this way to simplify the overall interface during the initial development of ROS2. This sets a bad precedent for clear ownership however, as you have pointed out.

oysstu gravatar image oysstu  ( 2020-11-06 04:48:27 -0600 )edit

Any updates on this? My team is trying to make the switch to ROS2 but have the exact same questions ...

jn42 gravatar image jn42  ( 2021-09-22 14:13:19 -0600 )edit

For an authoritative answer, we'll need input from someone who was present when this design choice was made.

Perhaps @William, or one of the other "core devs" of ROS 2.

gvdhoorn gravatar image gvdhoorn  ( 2021-09-22 14:22:31 -0600 )edit

Though not a direct and complete answer to your question, when I was searching for the same question I found the ROS 2 design article Intra-process Communications in ROS 2 that provides interesting information on using different type of smart pointers for publishers and subscribers

mateussmenezes gravatar image mateussmenezes  ( 2022-11-16 17:16:12 -0600 )edit

1 Answer

Sort by » oldest newest most voted

answered 2020-11-17 04:35:13 -0600

fredBeauj gravatar image

I wasn't involved in the design decision but asked myself the same question as @nnmm . One thing I noticed is that shared pointers are pervasive in that if you use shared_from_thisinside the class definition (and that happens quite a bit) so the node can pass itself to members, then it would be undefined behavior until C++17 if the node wasn't created as a shared pointer; cf

Certainly not great to require knowing how your instance is created/stored but that's how it is.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2020-10-09 07:48:53 -0600

Seen: 2,478 times

Last updated: Nov 17 '20