其他分享
首页 > 其他分享> > 如何根据c标准访问对象表示?

如何根据c标准访问对象表示?

作者:互联网

如何访问object representation?为了回答这个问题,我将其分为两个问题:

1.如何获取对象表示的指针?

根据标准,我看不到任何获取对象表示形式的指针的方法.通常建议以这种方式获取它:

some_type obj{};
const char * rep = reinterpret_cast<const unsigned char*>(&obj);

然而,在标准中并没有说一个对象及其对象表示是指针可互换的.为什么标准允许使用此代码?

2.当对象初始化时,我们是否可以认为对象表示已初始化?

some_type obj{};
const char * rep = reinterpret_cast<const unsigned char*>(&obj);
char x = rep[0] + rep[1];

这里obj是默认初始化的.编译器如何解释rep [0],是一个不确定的值,还是取决于obj初始化期间已初始化了哪些内存字节?

解决方法:

1)您的方法有效:

使用const指针可确保不丢弃constness:

5.2.10/2 The reinterpret_cast operator shall not cast away constness.

指针转换是安全的,因为char对对齐的要求不比some_type严格,因此您可以将rep转换回some_type *:

5.2.10/7 An object pointer can be explicitly converted to an object pointer of a different type. (…) Converting a prvalue of type
“pointer to T1” to the type “pointer to T2” (where T1 and T2 are
object types and where the alignment requirements of T2 are no
stricter than those of T1) and back to its original type yields the
original pointer value.

编辑:根据我的理解,毫无疑问,指向对象的指针与指向其表示的指针之间的可互换性:

1.8/6: Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first
byte it occupies.

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.1/3: (…) if the type of the expression is T, the result has type “pointer to T” and is a prvalue that is the address of the
designated object

2)用对象初始化对象表示:

这是由值表示的定义以及内存模型和对象生命周期引起的.

但是,您的示例更为复杂:

> rep [0]尽管具有仅由填充位组成的属性,但仍可能具有不确定的值.在您的示例中就是这种情况,因为对象的大小至少为1,但是由于其中没有成员,因此值表示为空.
如果sizeof(some_type)小于2,则rep [1]可能是未定义的行为,因为取消引用通过数组最后一个元素的指针是UB.

3)什么是对象表示(用简单的语言表示)?

让我们举一个简单的例子:

class some_other_type {
    int a;
    std::string s;
};

在谈论对象占用的内存时有一个歧义:

>仅仅是与它的类型相对应的固定大小的连续内存吗(即int,某个string_length的一些size_t和该字符串中char的一些指针,就像在C中那样)?
>还是所有存储在对象内存中的值,包括存储在其他地方分配的内存中的某些值(例如,存储字符串值所需的字节)?

对象表示对应于第一部分.对于无法简单复制的对象,对象表示形式本身并不足够(即,在我们的示例中,存储在字符串中的字节不一定是对象表示形式的一部分).

值表示形式对应于第二部分(并将包括存储字符串值所需的字节).

简而言之,这意味着对象的地址就是其表示的地址,但是对象的表示可能包含填充并且可能不足以容纳属于该对象的每个数据.

标签:c,language-lawyer,undefined-behavior,pointers,object
来源: https://codeday.me/bug/20191009/1882283.html