能否从指向子对象的指针获得指向完整对象表示元素的指针?

Can one get a pointer to a complete object representation element from a pointer to a suboject?

让我们考虑一下这段代码:

int i;
int is[10]{};

unsigned char * p = reinterpret_cast<unsigned char*>(&i);
//p defined to point to the object-representation of the first element of array ints
unsigned char * ps = reinterpret_cast<unsigned char*>(&is[0]);

p += sizeof(int);
ps += sizeof(int);
//now ps points to the end of ints[0] and p point to the end of i;

p += sizeof(int); //Undefined behavior according to [expr.add]

ps += sizeof(int); //Undefined behavior?
unsigned char c = *ps;//Undefined behavior?

如果我们认为ps指向is[0]object-representation,那么根据指针运算规则,在最后两行代码处行为未定义。

然而,如果 ps 也是指向 object-representation 的 int is 数组的指针,则行为已定义。

所以我的问题是:指向 subojectobject-representation 的指针是否也是指向 object 的元素的指针-representation 包含完整对象?

没有 "pointer to the object representation" 这样的东西。您有一个保存对象地址的指针,可以安全或不安全地派生该指针。

当您使用窄字符类型的左值在对象的地址范围内读取时,"object representation" 开始发挥作用,而不是在形成或转换指针时。

reinterpret_cast<unsigned char*>(p) 的规则中没有任何关于结果 "pointer to object representation" 的特殊说明。它仍然只是同一对象的另一个别名。

一般情况

是的,指向子对象的对象表示的指针也是指向包含完整对象的对象表示的一部分的指针。

这可以推导出:

1.8/1: An object is a region of storage.

3.9/4: The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).

5.3.3/1: The sizeof operator yields the number of bytes in the object representation of its operand.

1.8/2: Objects can contain other objects, called subobjects. A subobject can be a member subobject, a base class subobject, or an array element. An object that is not a subobject of any other object is called a complete object.

对象是存储区域并且子对象包含在存储区域中这一事实意味着子对象表示包含在对象表示中。

中所述,指向对象表示的指针实际上是指向对象的指针。

数组的具体情况

是的,指向子对象的对象表示(即在本例中为数组元素)的指针是指向 包含完整对象表示的元素的指针对象(即在本例中为数组)。

8.4.3/1: (...) An object of array type contains a contiguously allocated non-empty set of N subobjects of type T. (...)

所以根据定义:

  • 数组的元素是连续分配的,也就是说元素之间没有空space。

  • 每个元素的对象表示是一个sizeof(T)个无符号字符的序列,完整数组的对象表示是生成的N*sizeof(T)个无符号字符。

然后我们可以推断:

  • 正如中所解释的,指向对象表示的指针实际上是指向对象的指针。

  • 数组中第k个元素的地址对应于数组对象表示中的第k个元素,构造偏移量为k*sizeof(T)数组表示的地址的无符号字符。

因此,只要您保持在 is

的边界内,您代码的最后 2 条语句就不是未定义的行为