Skip to content

Commit 8499404

Browse files
authored
Added static assert asserting custom types have no overloaded operator new (#2954)
Signed-off-by: Ivo Ivanov <[email protected]>
1 parent 715a983 commit 8499404

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

rclcpp/include/rclcpp/publisher.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,13 @@ class Publisher : public PublisherBase
574574
std::unique_ptr<PublishedType, PublishedTypeDeleter>
575575
duplicate_type_adapt_message_as_unique_ptr(const PublishedType & msg)
576576
{
577+
/// Assert that the published type has no overloaded operator new since this leads to
578+
/// new/delete mismatch (see https://github.com/ros2/rclcpp/issues/2951)
579+
static_assert(!detail::has_overloaded_operator_new_v<PublishedType>,
580+
"When publishing by value (i.e. when calling publish(const T& msg)), the published "
581+
"message type must not have an overloaded operator new. In this case, please use the "
582+
"publish(std::unique_ptr<T> msg) method instead.");
583+
577584
auto ptr = PublishedTypeAllocatorTraits::allocate(published_type_allocator_, 1);
578585
PublishedTypeAllocatorTraits::construct(published_type_allocator_, ptr, msg);
579586
return std::unique_ptr<PublishedType, PublishedTypeDeleter>(ptr, published_type_deleter_);

rclcpp/include/rclcpp/type_adapter.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define RCLCPP__TYPE_ADAPTER_HPP_
1717

1818
#include <type_traits>
19+
#include <new>
1920

2021
namespace rclcpp
2122
{
@@ -128,6 +129,24 @@ struct assert_type_pair_is_specialized_type_adapter
128129
"No type adapter for this custom type/ros message type pair");
129130
};
130131

132+
template<typename, typename = void>
133+
struct has_overloaded_operator_new : std::false_type {};
134+
template<typename T>
135+
struct has_overloaded_operator_new<T, std::void_t<
136+
decltype(T::operator new(std::size_t()))
137+
>>: std::true_type {};
138+
139+
template<typename, typename = void>
140+
struct has_overloaded_aligned_operator_new : std::false_type {};
141+
template<typename T>
142+
struct has_overloaded_aligned_operator_new<T,
143+
std::void_t<decltype( T::operator new(std::size_t(), std::align_val_t()) )>>
144+
: std::true_type {};
145+
146+
template<typename T>
147+
inline constexpr bool has_overloaded_operator_new_v = has_overloaded_operator_new<T>::value ||
148+
has_overloaded_aligned_operator_new<T>::value;
149+
131150
} // namespace detail
132151

133152
/// Template metafunction that can make the type being adapted explicit.

0 commit comments

Comments
 (0)