ros / roscpp_core

ros distribution sandbox
88 stars 116 forks source link

Compile errors with gcc-10 and -std=gnu++2a option #125

Closed pauljurczak closed 1 year ago

pauljurczak commented 3 years ago

I'm using ROS Melodic on Ubuntu 18.04.5 with gcc-10.1. This test program compiles and runs fine with -std=gnu++17 option, but fails to compile with -std=gnu++2a:

#include <iostream>
#include <ros/ros.h>
#include <ros/callback_queue.h>
#include <sensor_msgs/Image.h>

using namespace std;

ros::NodeHandle* nodeHandle;  
ros::Subscriber* imageSubsc;
int   imageId{-1}, prevImageId{-1};
float imageStamp{-1};

void imageCallback(const sensor_msgs::Image::ConstPtr& message) {
  imageId    = message->header.seq;
  imageStamp = message->header.stamp.sec + 1e-9 * message->header.stamp.nsec;
  cout << fixed << setprecision(3) << ros::Time::now().toSec() << "  " << imageStamp << "  " << imageId << " * callback" << endl;
}

int main(int argc, char* argv[]) {
  ros::init(argc, argv, "igntest");
  cout << "Testing: /X1/front_rgbd/image_raw" << endl;
  ros::Time::init();
  ros::Duration(10.0).sleep();

  nodeHandle = new ros::NodeHandle; // this will create the node and make it visible to ROS 
  imageSubsc = new ros::Subscriber(nodeHandle->subscribe<sensor_msgs::Image>("/X1/front_rgbd/image_raw", 1, imageCallback, ros::TransportHints().tcpNoDelay()));

  ros::Duration(10.0).sleep();

  for (int i = 0; i < 50; i++) {
    ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0.1));
    cout << fixed << setprecision(3) << ros::Time::now().toSec() << "  " << imageStamp << "  " << imageId;
    cout << (prevImageId == imageId ? " * sequence number repeated!" : "") << endl;
    prevImageId = imageId;
  }
}

Here is the error message:

[build] [1/2  50% :: 2.581] Building CXX object CMakeFiles/ign-test.dir/main.cpp.o
[build] FAILED: CMakeFiles/ign-test.dir/main.cpp.o 
[build] /usr/local/bin/cmake -E time /usr/bin/g++-10 -DROSCONSOLE_BACKEND_LOG4CXX -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"ign-test\" -I/home/paul/subt_ws/install/include -I/opt/ros/melodic/include -I/opt/ros/melodic/share/xmlrpcpp/cmake/../../../include/xmlrpcpp -O3 -DNDEBUG -std=gnu++2a -MD -MT CMakeFiles/ign-test.dir/main.cpp.o -MF CMakeFiles/ign-test.dir/main.cpp.o.d -o CMakeFiles/ign-test.dir/main.cpp.o -c ../main.cpp
[build] In file included from /opt/ros/melodic/include/sensor_msgs/Image.h:18,
[build]                  from ../main.cpp:4:
[build] /opt/ros/melodic/include/std_msgs/Header.h: In instantiation of ‘struct std_msgs::Header_<std::allocator<void> >’:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:50:16:   required from ‘struct sensor_msgs::Image_<std::allocator<void> >’
[build] ../main.cpp:13:44:   required from here
[build] /opt/ros/melodic/include/std_msgs/Header.h:46:121: error: no class template named ‘rebind’ in ‘class std::allocator<void>’
[build]    46 |    typedef std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other >  _frame_id_type;
[build]       |                                                                                                                         ^~~~~~~~~~~~~~
[build] In file included from ../main.cpp:4:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h: In instantiation of ‘struct sensor_msgs::Image_<std::allocator<void> >’:
[build] ../main.cpp:13:44:   required from here
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:58:121: error: no class template named ‘rebind’ in ‘class std::allocator<void>’
[build]    58 |    typedef std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other >  _encoding_type;
[build]       |                                                                                                                         ^~~~~~~~~~~~~~
[build] In file included from ../main.cpp:4:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:67:97: error: no class template named ‘rebind’ in ‘class std::allocator<void>’
[build]    67 |    typedef std::vector<uint8_t, typename ContainerAllocator::template rebind<uint8_t>::other >  _data_type;
[build]       |                                                                                                 ^~~~~~~~~~
[build] In file included from ../main.cpp:4:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h: In instantiation of ‘sensor_msgs::Image_<ContainerAllocator>::Image_() [with ContainerAllocator = std::allocator<void>]’:
[build] /usr/include/boost/smart_ptr/make_shared_object.hpp:256:5:   required from ‘typename boost::detail::sp_if_not_array<T>::type boost::make_shared(Args&& ...) [with T = sensor_msgs::Image_<std::allocator<void> >; Args = {}; typename boost::detail::sp_if_not_array<T>::type = boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >]’
[build] /opt/ros/melodic/include/ros/message_event.h:53:33:   required from ‘boost::shared_ptr<X> ros::DefaultMessageCreator<M>::operator()() [with M = sensor_msgs::Image_<std::allocator<void> >]’
[build] /usr/include/boost/function/function_template.hpp:138:22:   required from ‘static R boost::detail::function::function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = ros::DefaultMessageCreator<sensor_msgs::Image_<std::allocator<void> > >; R = boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >]’
[build] /usr/include/boost/function/function_template.hpp:925:38:   required from ‘void boost::function0<R>::assign_to(Functor) [with Functor = ros::DefaultMessageCreator<sensor_msgs::Image_<std::allocator<void> > >; R = boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >]’
[build] /usr/include/boost/function/function_template.hpp:716:22:   required from ‘boost::function0<R>::function0(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = ros::DefaultMessageCreator<sensor_msgs::Image_<std::allocator<void> > >; R = boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
[build] /usr/include/boost/function/function_template.hpp:1061:16:   required from ‘boost::function<R()>::function(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = ros::DefaultMessageCreator<sensor_msgs::Image_<std::allocator<void> > >; R = boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
[build] /opt/ros/melodic/include/ros/node_handle.h:707:25:   required from ‘ros::Subscriber ros::NodeHandle::subscribe(const string&, uint32_t, void (*)(const boost::shared_ptr<const M>&), const ros::TransportHints&) [with M = sensor_msgs::Image_<std::allocator<void> >; std::string = std::__cxx11::basic_string<char>; uint32_t = unsigned int]’
[build] ../main.cpp:26:158:   required from here
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:34:12: error: using invalid field ‘sensor_msgs::Image_<ContainerAllocator>::encoding’
[build]    34 |     , data()  {
[build]       |            ^
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:34:12: error: using invalid field ‘sensor_msgs::Image_<ContainerAllocator>::data’
[build] In file included from ../main.cpp:4:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h: In instantiation of ‘static void ros::serialization::Serializer<sensor_msgs::Image_<ContainerAllocator> >::allInOne(Stream&, T) [with Stream = ros::serialization::IStream; T = sensor_msgs::Image_<std::allocator<void> >&; ContainerAllocator = std::allocator<void>]’:
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:256:5:   required from ‘static void ros::serialization::Serializer<sensor_msgs::Image_<ContainerAllocator> >::read(Stream&, T&) [with Stream = ros::serialization::IStream; T = sensor_msgs::Image_<std::allocator<void> >; ContainerAllocator = std::allocator<void>]’
[build] /opt/ros/melodic/include/ros/serialization.h:163:22:   required from ‘void ros::serialization::deserialize(Stream&, T&) [with T = sensor_msgs::Image_<std::allocator<void> >; Stream = ros::serialization::IStream]’
[build] /opt/ros/melodic/include/ros/subscription_callback_helper.h:136:21:   required from ‘ros::VoidConstPtr ros::SubscriptionCallbackHelperT<P, Enabled>::deserialize(const ros::SubscriptionCallbackHelperDeserializeParams&) [with P = const boost::shared_ptr<const sensor_msgs::Image_<std::allocator<void> > >&; Enabled = void; ros::VoidConstPtr = boost::shared_ptr<const void>]’
[build] /opt/ros/melodic/include/ros/subscription_callback_helper.h:118:24:   required from here
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:250:21: error: ‘struct sensor_msgs::Image_<std::allocator<void> >’ has no member named ‘encoding’
[build]   250 |       stream.next(m.encoding);
[build]       |                   ~~^~~~~~~~
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:253:21: error: ‘struct sensor_msgs::Image_<std::allocator<void> >’ has no member named ‘data’
[build]   253 |       stream.next(m.data);
[build]       |                   ~~^~~~
[build] In file included from /opt/ros/melodic/include/sensor_msgs/Image.h:18,
[build]                  from ../main.cpp:4:
[build] /opt/ros/melodic/include/std_msgs/Header.h: In instantiation of ‘static void ros::serialization::Serializer<std_msgs::Header_<ContainerAllocator> >::allInOne(Stream&, T) [with Stream = ros::serialization::IStream; T = std_msgs::Header_<std::allocator<void> >&; ContainerAllocator = std::allocator<void>]’:
[build] /opt/ros/melodic/include/std_msgs/Header.h:197:5:   required from ‘static void ros::serialization::Serializer<std_msgs::Header_<ContainerAllocator> >::read(Stream&, T&) [with Stream = ros::serialization::IStream; T = std_msgs::Header_<std::allocator<void> >; ContainerAllocator = std::allocator<void>]’
[build] /opt/ros/melodic/include/ros/serialization.h:163:22:   required from ‘void ros::serialization::deserialize(Stream&, T&) [with T = std_msgs::Header_<std::allocator<void> >; Stream = ros::serialization::IStream]’
[build] /opt/ros/melodic/include/ros/serialization.h:719:16:   required from ‘void ros::serialization::IStream::next(T&) [with T = std_msgs::Header_<std::allocator<void> >]’
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:247:18:   required from ‘static void ros::serialization::Serializer<sensor_msgs::Image_<ContainerAllocator> >::allInOne(Stream&, T) [with Stream = ros::serialization::IStream; T = sensor_msgs::Image_<std::allocator<void> >&; ContainerAllocator = std::allocator<void>]’
[build] /opt/ros/melodic/include/sensor_msgs/Image.h:256:5:   required from ‘static void ros::serialization::Serializer<sensor_msgs::Image_<ContainerAllocator> >::read(Stream&, T&) [with Stream = ros::serialization::IStream; T = sensor_msgs::Image_<std::allocator<void> >; ContainerAllocator = std::allocator<void>]’
[build] /opt/ros/melodic/include/ros/serialization.h:163:22:   required from ‘void ros::serialization::deserialize(Stream&, T&) [with T = sensor_msgs::Image_<std::allocator<void> >; Stream = ros::serialization::IStream]’
[build] /opt/ros/melodic/include/ros/subscription_callback_helper.h:136:21:   required from ‘ros::VoidConstPtr ros::SubscriptionCallbackHelperT<P, Enabled>::deserialize(const ros::SubscriptionCallbackHelperDeserializeParams&) [with P = const boost::shared_ptr<const sensor_msgs::Image_<std::allocator<void> > >&; Enabled = void; ros::VoidConstPtr = boost::shared_ptr<const void>]’
[build] /opt/ros/melodic/include/ros/subscription_callback_helper.h:118:24:   required from here
[build] /opt/ros/melodic/include/std_msgs/Header.h:194:21: error: ‘struct std_msgs::Header_<std::allocator<void> >’ has no member named ‘frame_id’
[build]   194 |       stream.next(m.frame_id);
[build]       |                   ~~^~~~~~~~
[build] Elapsed time: 3 s. (time), 0.000461 s. (clock)
AndrewLipscomb commented 3 years ago

Necroing a bit but this is a deprecation

https://en.cppreference.com/w/cpp/memory/allocator Specifically

rebind (deprecated in C++17)(removed in C++20)

There are no good workarounds here given these are public headers. If you want to mix and match ROS Melodic or Noetic and ++20 - you'll need to split out library targets and give them their own C++ standards rules.

johannes-graeter commented 3 years ago

If I am not mistaken this should be fixed by an ongoing PR (https://github.com/ros/roscpp_core/pull/124) that was filed 6 months ago...