RFC: using C++14

Hello friends@sig-ng,

An excellent issue report and set of pull-requests was recently submitted:

The issue report is in regards to the potential perils of including global custom C++11 literals, which we’re using to simplify syntax when specifying durations using std::chrono. Fortunately, there are now standardized duration literals in C++14 that are supported on all compilers we are currently targeting. By moving to C++14, we can use those standardized literals for time/duration, rather than creating our own.

So, we propose to target C++14 for the upcoming ROS 2 beta. There are a few other features that also seem quite nice in C++14 and could simplify/shorten the codebase over time, such as std::make_unique, return auto, and so on:

Because C++14 seems to be well-supported now by modern toolchains, we do not expect this to be disruptive to anyone [1]. However, please discuss on this thread if you feel otherwise, so we can better understand your use case. Conversely, if you’re a big fan of C++14 for various reasons, please chime in!

Cheers,
-mq

[1] the potential breakages described in this post seem relatively minor: http://stackoverflow.com/a/23980931

3 Likes

I can’t think of any reason for not switching to C++14, besides compiler support. Support for C++14 in GCC and Clang is complete, but VS2015 seems to be lacking:

https://msdn.microsoft.com/en-us/library/hh567368.aspx

In any case, VS2017 is around the corner. In the meantime, it’d might be useful to enable C++14 in VS2015 and see if anything breaks, and then start introducing new features in ROS2 (e.g. std::make_unique):

https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-compiler/

C++14 is pretty great. You can do stuff like this:

auto my_function() {
return SomethingWithAComplicatedReturnType();
}

auto crazy_generic_lambda = [](auto generic_parameter, int known_typed_parameter){
return generic_parameter + known_typed_parameter;
};

1 Like

If C++ is asymptotically approaching Python, then should we just give up now and do everything in Python? :slight_smile:

2 Likes

Depends on how much you like strong typing and C backwards compatibility :stuck_out_tongue:

Depends on how much you care about sane notions of scope… :grimacing:

As you mentioned: the only thing that restrains moving to C++14 is the compiler support.
As far as I know there were some efforts building ROS2 on arm microcontrollers. Perhaps it would be wise to check if the most common compilers for embedded platforms are supporting C++14.

The arm-gcc-none-eabi compiler that is often used for STM32Fxxx series supports C++14. ( https://cppembedded.wordpress.com/tag/c14/ )

The toolchain supports it (except maybe the ARM stuff mentioned by @firesurfer), and ROS2 isn’t even in beta yet, so I’m all for requiring C++14.

This is only tangentially related to the question of “should we use C++14”, but anyway this is an attempt to simplify the minimal examples using generic lambas:

For example, this C++11 code:

subscription_ = this->create_subscription<std_msgs::msg::String>(
  "topic",
  [](std_msgs::msg::String::UniquePtr msg) {
  printf("I heard: [%s]\n", msg->data.c_str());
});

requires the message type to be listed twice: once for the create_subscription<> template, and once for the lambda parameter. It would be nice if we could do this:

subscription_ = this->create_subscription<std_msgs::msg::String>(
  "topic", [](auto msg) {
  printf("I heard: [%s]\n", msg->data.c_str());
});

However, that code change explodes spectacularly into a few hundred lines of gcc errors.

Does anybody know if that style of usage (mixing generic lambas with template instantiations) is just impossible in C++14 ? The overlap between lambdas and templates still seems a bit mysterious to me.

The second example (the one with auto msg in the lambda) is ambiguous, I think. What should the type of msg be? std_msgs::msg::String::ConstSharePtr or std_msgs::msg::String::UniquePtr or something else? I don’t think the compiler can implicitly infer which type you mean in this situation.

What you’re doing might work if you also supplied the CallbackT template argument to create_subscription.

I’ll play around with the example and see if I can simplify it. It should be possible, in principle, to do implicit template specialization on the create_subscription method, such that you can drop the <std_msgs::msg::String> explicit template specialization. Then you’d just need to explicitly type the msg parameter to the lambda.

I wrote a quick hack to remove the need to pass message type as a template argument in Node::create_subscription and submitted it as a pull request in https://github.com/ros2/rclcpp/pull/286 and updated some of the examples in https://github.com/ros2/examples/pull/146

I haven’t tested this heavily, and unfortunately the changes fail to compile the allocator example :frowning:

PS: when in doubt, rclcpp:function_traits, that’s my motto.

1 Like

It was a very silly bug, just fixed the order of the parameters in the template list and the allocator example compiles again:

https://github.com/ros2/rclcpp/pull/286/commits/444c8e0bc9dd13c2e3bed5a986574b6b979861a8

1 Like

We were hoping to target ROS2 development on the IntegrityOS, since they’ve recently updated their compiler to be C++11 compliant.
Pushing to C++14 will stop any hopes of deploying to a GreenHills IntegrityOS environment. :frowning:

GreenHills seemed like a favorable target since most DDS vendors sell a compliant version for Integrity, and GreenHills is big in the Safety space (getting safety ratings like SIL2 or ASILC, etc). So for critical components of vehicle automation systems, it would have been really great to have your lower-level safety components running ROS2 and also your high-level stuff.

Hi @SecretaryBirds, That’s unfortuate to hear. Thank you for raising this issue.

Has Green Hills provided a timetable for when their compiler will support C++14? Because the difference between C++14 and C++11 is much smaller than the difference between C++11 and C++0x, hopefully they will pick it up soon (?)

@SecretaryBirds, yours is an interesting use case for us. IntegrityOS is not one of our supported platforms, but if there’s something that could be done to make life easier there, we’re interested in discussing it. But first, as @codebot said, we’d like to learn more about what is and isn’t supported from the C++ spec on IntegrityOS, as well as what their future plans are in that regard. We’ve poked around a bit on the GreenHills site, but haven’t found much public information.

ROS 2 will be used for a long time after its release, probably a decade for new development and much longer in maintenance. Requiring users to work within the limits of C++ 11 for that period seems very restrictive. ROS 2 should support the latest version of C++ available for mainstream system when it is released. Let the end users push the vendors to provide the compiler support on systems that don’t keep up.

3 Likes

While I like to use the latest and greatest myself whenever i can, I think you have it a bit backwards. If the baseline for ROS2 development is C++11 or 14 or whatever, that should not prevent you from using it with more recent standards in your own code. The inverse however, is not true, so ROS 2 should continue to support the initialially chosen baseline dependencies for some period if time. I find that more often than not ROS is not the only dependency.

Long term support with stable dependencies is important. I believe the distribution model of ROS 1 works quite well in that case.

In any case I also agree that C++14 at this point makes sense for ROS2 beta.

I will have to consult with some of my colleagues about what their support roadmap is.
Although I wouldn’t hesitate to say it’ll be a slow transition.

Even if ROS2 isn’t supported on that platform, DDS is, and we can still interoperate. It would have just made things cleaner and simpler from a Platform/Ecosystem perspective if everything we create was on the same foundation.

The issue with IntegrityOS supporting C++14 is not the difference in feature set, but the time and cost required to certify their compiler and tool chain again. Unfortunately, certification methods don’t cope well with re-certifying modified software; you often have to treat it as a whole new system. If IntegrityOS has only recently got C++11 support certified then I don’t have much hope that C++14 will be coming very soon, but maybe they have a well-oiled certification programme and we’ll get lucky.