通常,指针减法的结果应该是std::ptrdiff_t
,这是一个有符号的类型。但是:
如果数组太大(大于PTRDIFF_MAX元素,但小于PTRDIFF_MAX元素) 大于SIZE_MAX字节),则两个指针之间的差异可能不会 可表示为std :: ptrdiff_t,减去两个这样的结果 指针是未定义的。
为防止进入未定义行为的领域,是否存在另一种合法(根据标准意图,而不是特定/通用实现)的类型,可以保留指针减法运算的结果而不必担心溢出?
尤其是,可以保证std::size_t
或std::uintptr_t
适用于存储这样的操作结果而不会发生上溢,下溢或未定义的行为(假设表达式{{1}中},a - b
大于a
,以防止下溢)?
答案 0 :(得分:1)
我不是语言律师,但是我有两个考虑要点-从理论上讲-可以计算两个合适的指针的“距离”。
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;
}