Ric*_*ges 12 c++ language-lawyer c++11 c++14 c++17
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()));
}
Run Code Online (Sandbox Code Playgroud)
请注意,a并b具有不同的访问说明符.
Bar*_*rry 10
指针比较在[expr.rel]/3-4中定义:
比较不等的指针对象定义如下:
- 如果两个指针指向同一数组的不同元素或其子对象,则指向具有较高下标的元素的指针比较大.
- 如果两个指针指向同一对象的不同非静态数据成员,或者指向这些成员的子对象,则递归地指向后面声明的成员的指针比较更大,前提是这两个成员具有相同的访问控制并且提供了它们的类不是联盟.
- 否则,两个指针都不会比另一个更大.
如果两个操作数p和q比较相等,则p <= q且p> = q两者都产生真,而pq都产生假.否则,如果指针p比指针q比较大,则p> = q,p> q,q <= p,并且q = p,并且q> p all yield false.否则,未指定每个运算符的结果.
我们可以从中得出什么结论?
有一个总次序的对象内的相同类型的指针,但没有秩序的指针不同的对象或不同的访问控制的不同子对象的.缺乏一般的指针顺序is_within_object()并不是很有意义.在您希望它返回的情况下true,它可以工作.在您希望它返回的情况下,false这些运算符的结果是未指定的?这不是一个非常有用的结果.
也就是说,我们确实以[比较]的形式存在一个巨大的漏洞:
为模板
less,greater,less_equal,和greater_equal,对于任何指针类型的特化收率是那些特例中是一致的,并且还与由内置的运营商所施加的偏序相一致的严格总订单<,>,<=,>=.
所以下面的定义很明确:
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);
}
Run Code Online (Sandbox Code Playgroud)