ROS 2 and C++20

I’m wondering what the plans of using C++20 as the default version are. C++17 was the default introduced in the Galactic distro in 2021. I can’t seem to find any information about when C++20 is going to be introduced in a ros2 distro. Will it be the default for the Jazzy distro? I understand I can compile a package with C++20 and it should/will/may work but I’m just wondering when it will become the default.

1 Like

We don’t have a definitive timeframe at the moment. That’s for two main reasons:

  1. Nobody has stepped up to do the work to support this. This would include making changes to the code itself (which AiVerisimilitude has done some of), plus updating all of the CMakeLists.txt to C++20.
  2. We have a “wide tent”, and some of our users (particularly those in safety-conscious settings) won’t be able to use C++20 anytime soon. We won’t wait for them forever (since the MISRA-style processes can take a long time), but 3 years isn’t enough time, in my opinion.

But I should ask: what specific parts of C++20 do you want to use?

2 Likes

@clalancette Thanks for the reply.

There are C++20 features that sometimes come up that I might want to use. Our developers have also asked on occasion whether C++20 is supported when they need a specific feature. In general, they are surprised that, given now that C++23 is out, we are two versions back. I guess I was just looking for a general timeline for introduction of C++20 but it looks like even that has not been determined. I am curious what the safety implications of C++20 were.

Generally, it is okay to use newer C++ versions as long as their features and flags do not end in public APIs.

I.e. using modules would not be possible, but e.g. some stdlib goodies would be okay to use if they are only used in the .cpp files.

There are not necessarily any specific safety implications of C++20, but the standards that must be conformed to in order to get safety certification generally take time to update and so lag a couple of versions behind the most recent version of the C++ standard.

Make sense. I would use it in our own application packages which won’t make it into any public APIs. I would have to compile those specific packages against C++20 in CMakeLists and then at some point when the C++20 becomes the default, remove that designation from the CMakeLists

@gbiggs That makes sense. However safety-conscious users should just use the version of the distro that has been safety-qualified with respect to the C++ version. It shouldn’t stop ros 2 from moving forward with the next version of C++.

I won’t be able to use it at work until the compiler considers C++20 fully supported.

“GCC has experimental support for the latest revision of the C++ standard, which was published in 2020… Important : Because the ISO C++20 standard is very recent, GCC’s support is experimental .”

https://gcc.gnu.org/projects/cxx-status.html

It is not really an option to be using an experimental version of a compiler on production code. If that changed tomorrow, then yes, I’d love to be able to use C++20.

1 Like

I always hated it when developers of some public library decided to mandate use of (the latest version of C++) when there was no actual specific value to do so.

General best rule of maintaining a public code resource: dont break backward compatibility unless you have a REALLY, REALLY GOOD reason to do so.

“I want to use the latest code prettifying hack” is not a good reason, in my opinion.

1 Like

Ha, welcome to OSS maintenance.

Using latest features/framework/language/something else vs maintaining bw-compatibility/only upgrading when needed is almost like spaces-vs-tabs.

4 Likes

Because the ISO C++20 standard is very recent, GCC’s support is experimental .”

very is doing some heavy lifting there. It is like saying, “Foxy is a very recent version of ROS 2”.

For maximum compatibility, why use C++ over C if compatibility is always more important than ergonomics and features of the language?

C++20 and C++23 are some of the most underwhelming releases of C++ compared to 11 and 17. Many blame COVID and the ISO process for being poorly designed for remote collaboration.

Concepts are excellent for library authors of templates. The brick operator and mdspan might have some interesting applications for the ergonomics of DSLs. PMR is probably the most relevant feature for robotics applications. Deducing this is a cool feature with many applications, go watch one of the Ben Dean talks on it. There are a few features that are not easily replicated without newer standards from 20 and 23.

4 Likes

There are a few features that are not easily replicated without newer standards from 20 and 23.

This is the second time in this thread I’ve seen mention of “a few features”, without any specifics.

How about mentioning even just one specifically, and explaining why you think it is worthwhile to go through a bunch of upgrade hassle?

Looking at your comments I feel that someone is speaking on the behalf of me. :slight_smile:

Here are a list of C++20 features I want to use in interfaces (header files):

  • concepts, reason: simplify code that uses enable_if and make it more readable
  • expected, reason: using today through a header file I vendored (tl_expected in ros) but it would be nice to just use it through the stl
  • operator<=>, reason: simplifying comparison overloads
  • ranges, reason: composable algorithmic code, I’m already using this sort of through a library called flux. Sadly it is implemented using C++20 so I can’t use flux in the public interface of ROS packages. This one heavily depends on the concepts feature.

Designated initializers is a C++20 feature that made it into C so unless you use -Wpedantic you can join me today and use it.

I thought I spelled out what features I wanted because you asked but noticed you also wanted reasons. Here are some reasons.

I’ve heard several people say they’d like to use PMR in their algorithmic code. I listed the features I know I want to use in the code I write and maintain. I’m not entirely convinced PMR is a good change in C++.

Here is a list of C++23 features I want to use as soon as possible:

  • deducing this, reason: simplifies code where you previously had to specify lvalue/rvalue overloads, simplifies CRTP
  • operator[] and mdspan, reason: ergonomic image transform code
3 Likes

Thanks @tylerweaver. I was going to reply with pretty much a similar set of features but you did a much better job than me.

I wanted to point an example of a minor C++20 feature that came up recently. A developer recently wanted to use map.contains(key) and I said it was only available in C++20. So the developer was resigned to using map.find(key) != map.end() or map.count(key) > 0, both of which are are poor substitutions for existence of a key in a map. My point here is not that this is a reason to move to C++20. It is that one of the goals of the evolution of C++ by the standards body is to make the language easier to use and understand. My example is admittedly a poor example but I can point to extremely complex written C++ code that can replicated in much simpler understandable syntax in languages like C# or Python, for example. And no, this is not a “code prettifying hack”. It is code that I write that I want myself and other developers to clearly understand the intention of the code a year or two from now, without having to “decipher” the meaning of the code. It leads to better code maintenance. The standards committee are continually introducing features that help make our code more expressive and intentional without sacrificing the performance guarantees of C++. This includes new language features, code semantics and new library features all of which are intended to improve the use and understandability of your code.

One more thing, maybe minor. If you want new developers joining the ros 2 ecosystem, then you most likely want to keep updating the ecosystem to the latest language features. Users are less likely to join the ros 2 ecosystem, if it is still stuck on C++14 and they have been using C++26 in their previous job.

I’m not minimizing the effort it takes to qualify the ros 2 core packages with C++20 - I’m sure that is a significant effort. But as an end user developing a ros 2 application, the fact that the latest ros 2 distro has made C++20 the default C++ version does not in any way mandate you to use C++20 in your own code. A developer is free to write his/her application using the constructs of any earlier version of C++ including C++98 if you so choose. That is the backwards compatibility guarantee of successive version of C++. The only time they have deprecated and removed features is when they are broken e.g. auto_ptr. You should be able to recompile your C++11 code and keep chugging along without using any of the newer language features. I have even found bugs in my existing application code when compiling with a newer compiler e.g. when there is stricter checking.

At some point, you have to move forward with the language so developers who want to use it can. The only question is when. You can make the same argument why we need to keep adding features to the ros 2 core and just stick with ‘foxy’ and just only fix bugs. The ros 2 distro upgrades are even worse since they break both source and binary compatibility. But that is acceptable to gain the new features.

3 Likes

Its not the same argument at all. You can add features to an API, while leaving existing ones in place. People who want to use the new features use them, and people who dont want to, dont, and everyone is happy.
Whereas changing the minimum compiler version, FORCES change on everyone.

That being said, some of the specific examples for C++20 do sound a little useful, at least
(Even if the rest of them are not, IMO :slight_smile: )

C++20 and C++23 is maybe 10% better than C++17. Rust is 10x better. The transition is 10x harder though. I’m happy to advocate lightly for upgrading C++ but if I have to choose what to spend my time on it will always be the future where we all worship a crab god.

Eh.
We already have python for “easy”, and C++ for “fast, lowlevel”. Moving from C++ to Rust is just replacing one “fast, lowlevel” implementation with another one. It’s not evolutionary.
Personally, what I’d like to see as a new direction for the future, is “easy, AND fast”. eg: golang support for everything.

I’m totally confused by this whole discussion, nobody prevents you from using C++20 in your own code. The ABI between c++17 and c++20 are fully compatible, so it does not matter what standard ros uses internally to compile their stuff.

Edit: Got it, this is the other way around, people wanting to compile ros2 on centos4 :stuck_out_tongue:

I feel like I shouldn’t make moveit2 require a C++20 compiler until ROS 2 does… but maybe no one would notice…

1 Like