存储指针减法的结果

时间:2018-08-16 22:33:43

标签: c++11 pointers types difference c++-standard-library

通常,指针减法的结果应该是std::ptrdiff_t,这是一个有符号的类型。但是:

  

如果数组太大(大于PTRDIFF_MAX元素,但小于PTRDIFF_MAX元素)   大于SIZE_MAX字节),则两个指针之间的差异可能不会   可表示为std :: ptrdiff_t,减去两个这样的结果   指针是未定义的。

为防止进入未定义行为的领域,是否存在另一种合法(根据标准意图,而不是特定/通用实现)的类型,可以保留指针减法运算的结果而不必担心溢出?

尤其是,可以保证std::size_tstd::uintptr_t适用于存储这样的操作结果而不会发生上溢,下溢或未定义的行为(假设表达式{{1}中},a - b大于a,以防止下溢)?

1 个答案:

答案 0 :(得分:1)

我不是语言律师,但是我有两个考虑要点-从理论上讲-可以计算两个合适的指针的“距离”。

  1. 一一计算指针之间​​的跳数
  2. 使用std::less和朋友来获取more guarantees on the total order(GCC does care

这在理论上对很有帮助,因为一一递增效率太低。请注意,在std::ptrdiff_t“不够”的情况下,线性成本最受损害。

#include <cassert>
#include <cstddef>

#include <functional>

template<class T>
constexpr std::size_t generalized_distance(T* first, T* last) {
// prefer `std::less_equal(first, last)` over `first <= last` because
// > it yields a strict total order even if the built-in operator<= does not
// (https://en.cppreference.com/w/cpp/utility/functional/less_equal)
  assert(std::less_equal{}(first, last));

  std::size_t number_of_hops = 0;
// `last` might be "one past the end" so let us be sure and increment one by one
  while(std::less{}(first, last)) {
    ++first;
    ++number_of_hops;
  }
  return number_of_hops;
}