intrusive icon indicating copy to clipboard operation
intrusive copied to clipboard

Type safety issues of s_iterator_to

Open CharlieQiu2017 opened this issue 1 year ago • 0 comments

Suppose that class A derives from set_base_hook < >, and class B derives from A. Now one can create an instance x of B and insert it into a container y (say, rbtree < B >). Then one can cast x into A & and use rbtree < A > :: s_iterator_to and rbtree < A > :: container_from_iterator to obtain a reference to y with type rbtree < A >, which I think should be undefined behavior, because one is accessing y through a different type.

Example:

#include <boost/intrusive/rbtree.hpp>

using boost::intrusive::set_base_hook;
using boost::intrusive::rbtree;

/* Base class */
struct uint64_rbnode : public set_base_hook < > {
  uint64_t data;
};

constexpr bool operator== (const uint64_rbnode &node1, const uint64_rbnode &node2) {
  return node1.data == node2.data;
}

constexpr bool operator> (const uint64_rbnode &node1, const uint64_rbnode &node2) {
  return node1.data > node2.data;
}

constexpr bool operator>= (const uint64_rbnode &node1, const uint64_rbnode &node2) {
  return node1.data >= node2.data;
}

constexpr bool operator< (const uint64_rbnode &node1, const uint64_rbnode &node2) {
  return node1.data < node2.data;
}

constexpr bool operator<= (const uint64_rbnode &node1, const uint64_rbnode &node2) {
  return node1.data <= node2.data;
}

/* Derived class */
struct uint64_rbnode_derived : uint64_rbnode { uint64_t another_data; };

int main () {
  rbtree < uint64_rbnode_derived > tree; /* Container of derived type */
  uint64_rbnode_derived node;
  node.data = 0;
  tree.push_back (node);
  auto iter = rbtree < uint64_rbnode > :: s_iterator_to (node); /* Iterator of container of base type */
  /* Reference to container of derived type, but with type of container of base type */
  auto & tree_ref = rbtree < uint64_rbnode > :: container_from_iterator (iter);
  return 0;
}

The current documentation of s_iterator_to (value) just says "value must be a reference to a value inserted in a list." I think it should be clarified that value must have exactly the same type as the template parameter T passed to the container.

CharlieQiu2017 avatar Mar 08 '25 16:03 CharlieQiu2017