ros2 / ros2/rclcpp

MessagePoolMemoryStrategy may not compile

Open
#1,972 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backlog
Dominant language
C++
Stars
805
Forks
564
Avg merge
1d 17h
Merged PRs (30d)
27

Description

Bug report

Required Info:

  • Operating System:
    • Ubuntu 22.04 (kernel: 5.15.0-1015-realtime)
  • Installation type:
    • from source (humble)
  • Version or commit hash:
    • humble
  • DDS implementation:
    • n/a
  • Client library (if applicable):
    • rclcpp (GCC 11.2.0)
Steps to reproduce issue

Try to refer to the rclcpp::strategies::message_pool_memory_strategy::MessagePoolMemoryStrategy<MessageT, Size, > type with template argument MessageT being a type with non-fixed size.
For instance, define a message type in Bytes.msg:

byte[] data

Then use this type for the memory strategy:

rclcpp::strategies::message_pool_memory_strategy::MessagePoolMemoryStrategy<my_package::msg::Bytes, some_size>
Expected behavior

The code should compile.

Actual behavior

Compilation fails with error:

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
Additional information

When checking the class definition of MessagePoolMemoryStrategy the issue becomes apparent:

template<
  typename MessageT,
  size_t Size,
  typename std::enable_if<
    rosidl_generator_traits::has_fixed_size<MessageT>::value
  >::type * = nullptr
>
class MessagePoolMemoryStrategy
  : public message_memory_strategy::MessageMemoryStrategy<MessageT>
{
...

The issue is caused by the way how template< bool B, class T = void > struct enable_if is used here.
The resulting struct only has a member type if B is true. Otherwise, no member type is generated and as result, accessing ::type is invalid.
So whenever rosidl_generator_traits::has_fixed_size<MessageT>::value evaluates to false, compilation of will fail, since the code always tries to access the type, no matter what.

A fix might look like this (not yet tested!):

template<
  typename MessageT,
  size_t Size,
  std::enable_if<
    rosidl_generator_traits::has_fixed_size<MessageT>::value,
    void*
  > = nullptr
>
class MessagePoolMemoryStrategy
  : public message_memory_strategy::MessageMemoryStrategy<MessageT>
{
...

Ideally the message pool should be scaled in a way to satisfy an upper bound for the size of individual messages.
Unfortunately, I don't see how this can be achieved with the current API.

Disclaimer

I am not an experienced ROS(2) user. I just tried to implement some benchmarks in a real-time environment. Maybe the short answer to this issue is "RTFM", but I could barely find more documentation than the real-time examples provided with ROS2 and the according tutorials in the docs and since the code causing the compilation error is in fact flawed, I decided to submit this as an issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with a variable-size Bytes.msg message and rclcpp::strategies::message_pool_memory_strategy::MessagePoolMemoryStrategy. Inspect the class definition and the std::enable_if template argument, then verify that the chosen change allows the example to compile while considering the unresolved upper-bound sizing concern.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.