gpt4 book ai didi

c++ - 检查子对象的地址是否在包含对象的范围内是否合法

转载 作者:IT老高 更新时间:2023-10-28 23:18:38 26 4
gpt4 key购买 nike

2 个问题:

  1. 以下代码是否具有良好的已定义行为?

  2. 是否有任何可能的 c++ 实现可以断言?

代码(c++11 及更高版本):

#include <cassert>
#include <utility>
#include <ciso646>

template<class T>
auto to_address(T* p) { return reinterpret_cast<unsigned char const*>(p); }

/// Test whether part is a sub-object of object
template<class Object, class Part>
bool is_within_object(Object& object, Part& part)
{
auto first = to_address(std::addressof(object)),
last = first + sizeof(Object);

auto p = to_address(std::addressof(part));

return (first <= p) and (p < last);
}

struct X
{
int a = 0;

int& get_a() { return a; }
int& get_b() { return b; }
private:

int b = 0;
};

int main()
{
X x;

assert(is_within_object(x, x.get_a()));
assert(is_within_object(x, x.get_b()));
}

请注意,ab 具有不同的访问说明符。

最佳答案

指针比较在 [expr.rel]/3-4 中定义:

Comparing unequal pointers to objects is defined as follows:

  • If two pointers point to different elements of the same array, or to subobjects thereof, the pointer to the element with the higher subscript compares greater.
  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control and provided their class is not a union.
  • Otherwise, neither pointer compares greater than the other.

If two operands p and q compare equal, p<=q and p>=q both yield true and pq both yield false. Otherwise, if a pointer p compares greater than a pointer q, p>=q, p>q, q<=p, and q=p, and q>p all yield false. Otherwise, the result of each of the operators is unspecified.

我们可以从中得出什么结论?

在一个对象中有一个总顺序相同类型的指针,但是指向不同对象或不同访问控制的不同子对象的指针没有顺序 .缺乏一般的指针总顺序使得 is_within_object()不是很有意义。在您期望它返回 true 的情况下, 有用。在您期望它返回 false 的情况下,这些运算符的结果是未指定的?这不是一个非常有用的结果。


说,我们确实有一个巨大的漏洞,形式为 [comparisons] :

For templates less, greater, less_­equal, and greater_­equal, the specializations for any pointer type yield a strict total order that is consistent among those specializations and is also consistent with the partial order imposed by the built-in operators <, >, <=, >=.

所以下面的定义是明确的:

template<class T> 
auto byte_address(T& p) {
return reinterpret_cast<std::byte const*>(std::addressof(p));
}

template<class Object, class Part>
bool is_within_object(Object& object, Part& part)
{
auto first = byte_address(object);
auto last = first + sizeof(Object);
auto p = byte_address(part);


return std::less_equal<std::byte*>{}(first, p) &&
std::less<std::byte*>{}(p, last);
}

关于c++ - 检查子对象的地址是否在包含对象的范围内是否合法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47610789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com