diff --git a/rcl/src/rcl/time.c b/rcl/src/rcl/time.c index 2132b9b..17ef21a 100644 --- a/rcl/src/rcl/time.c +++ b/rcl/src/rcl/time.c @@ -218,9 +218,9 @@ rcl_difference_times( } if (finish->nanoseconds < start->nanoseconds) { rcl_time_point_value_t intermediate = start->nanoseconds - finish->nanoseconds; - delta->nanoseconds = -1 * (int) intermediate; + delta->nanoseconds = -1 * (int64_t) intermediate; } else { - delta->nanoseconds = (int)(finish->nanoseconds - start->nanoseconds); + delta->nanoseconds = (int64_t)(finish->nanoseconds - start->nanoseconds); } return RCL_RET_OK; } diff --git a/rcl/test/rcl/test_time.cpp b/rcl/test/rcl/test_time.cpp index f13283c..8955092 100644 --- a/rcl/test/rcl/test_time.cpp +++ b/rcl/test/rcl/test_time.cpp @@ -279,6 +279,58 @@ TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), rcl_time_difference) { EXPECT_EQ(d.nanoseconds, -1000); } +TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), rcl_time_difference_signed) { + rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_clock_t * ros_clock = + reinterpret_cast(allocator.allocate(sizeof(rcl_clock_t), allocator.state)); + rcl_ret_t retval = rcl_ros_clock_init(ros_clock, &allocator); + EXPECT_EQ(retval, RCL_RET_OK) << rcl_get_error_string_safe(); + + rcl_time_point_t a, b; + a.nanoseconds = RCL_S_TO_NS(0LL) + 0LL; + b.nanoseconds = RCL_S_TO_NS(10LL) + 0LL; + a.clock_type = RCL_ROS_TIME; + b.clock_type = RCL_ROS_TIME; + + { + rcl_duration_t d; + rcl_ret_t ret; + ret = rcl_difference_times(&a, &b, &d); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(d.nanoseconds, RCL_S_TO_NS(10LL)); + } + + { + rcl_duration_t d; + rcl_ret_t ret; + ret = rcl_difference_times(&b, &a, &d); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(d.nanoseconds, RCL_S_TO_NS(-10LL)); + } + + // Construct example from issue. + a.nanoseconds = RCL_S_TO_NS(1514423496LL) + 0LL; + b.nanoseconds = RCL_S_TO_NS(1514423498LL) + 147483647LL; + + { + rcl_duration_t d; + rcl_ret_t ret; + ret = rcl_difference_times(&a, &b, &d); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(d.nanoseconds, 2147483647LL); + } + + { + rcl_duration_t d; + rcl_ret_t ret; + ret = rcl_difference_times(&b, &a, &d); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + // The erroneous value was -2147483648 (https://github.com/ros2/rcl/issues/204) + EXPECT_EQ(d.nanoseconds, -2147483647LL); + } +} + + static bool pre_callback_called = false; static bool post_callback_called = false;