如何根据c ++标准访问对象表示? [英] How to access an object representation according to the c++ standard?

查看:68
本文介绍了如何根据c ++标准访问对象表示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何访问对象表示?为了回答这个问题,我将其分为两个问题:

How to access object representation? To answer this question I divide it in 2 questions:

根据标准,我看不到任何获取 object-representation 指针的方法.通常建议以这种方式获取它:

According to the standard I can not see any way to get a pointer to an object-representation. It is often proposed to get it this way:

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

尽管如此,在标准中并没有说 object 及其 object-representation pointer-interconvertible .为什么标准允许使用此代码?

Nevertheless, it is not said in the standard that an object and its object-representation are pointer-interconvertible. Why is this code allowed by the standard?

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

此处obj是默认初始化的.

Here obj is default initialized. How the compiler interpret rep[0], is it an indeterminate-value, or may be it depends on what bytes of memory have been initialized during obj initialization?

推荐答案

1)您的方法有效:

使用const指针可确保不会丢失常量性:

1) Your approach works:

Working with const pointers ensure that constness is not casted away:

5.2.10/2 .reinterpret_cast运算符不得放弃常数.

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

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

The pointer conversion is safe, because char has not a stricter alignment requirement than some_type, so that you may convert rep back to a some_type*:

5.2.10/7 可以将对象指针显式转换为其他类型的对象指针. (...)转换类型的prvalue 指向T1的指针"类型为指向T2的指针"(其中T1和T2是 对象类型以及T2的对齐要求是否为否 比T1严格),并返回到原始类型会产生 原始指针值.

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.

在我的理解中,毫无疑问,指向对象的指针和指向其表示的指针之间的可互换性:

In my understanding, there is no doubt about inter-convertibility between the pointer to an object and the pointer to its representation:

1.8/6:除非对象是位域或大小为零的基类子对象,否则该对象的地址为第一个对象的地址 它占用的字节.

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:类型为T 的对象的对象表示形式是该对象占用的N个无符号字符对象的序列 属于T型 其中N等于sizeof(T).

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).

我了解占用"是占用"的同义词.另请注意,&运算符保证:

I understand that "taken up" is a synonym of "occupies". Note also that, the & operator guarantees that:

5.3.1/3:(...)如果表达式的类型为T,则结果的类型为指向T的指针",并且是一个prvalue,它是该对象的地址. 指定对象

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)用对象初始化对象表示:

这是根据值表示的定义以及内存模型和对象生命周期得出的.

2) The object representation is initialized with the object:

This is induced from the definition of the value representation, taken together with the memory model and the object lifecylcle.

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

However, your example is more complex:

    如果
  • rep[0]仅由填充位组成,则尽管具有此属性,也可能保持不确定的值.在您的示例中就是这种情况,因为对象的大小至少为1,但是由于其中没有成员,所以值表示为空.
  • 如果sizeof(some_type)<2,则
  • rep[1]可能是未定义的行为,因为取消引用传递给数组最后一个元素的指针是UB.
  • rep[0] may despite this property remain an undetermined value, if it is composed solely of padding bits. This is the case in your example, because the object has at least a size of 1, but as you have no member in it, the value representation is empty.
  • rep[1] can be undefined behavior, if sizeof(some_type)<2 because dereferencing a pointer passed the last element of an array is UB.

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

Let's take a simple example:

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

谈论对象所占用的内存时存在歧义:

There is an ambiguity when speaking about the memory occupied by an object:

  • 是否只是与其类型相对应的固定大小的连续内存(即int,一些size_t表示字符串的长度,还有一些指向字符串中char的指针,就像在C中那样)?
  • 还是存储在对象内存中的所有值,包括存储在其他地方分配的内存位置中的某些值(例如,存储字符串值所需的字节)?
  • is it only the fixed size contiguous memory corresponding to the its type (i.e. an int, some size_t for the string's length and some pointer to the chars in the string, like it would be done in C) ?
  • or is it all the values stored in memory for the object, including at some values stored in memory places allocated somewhere else (e.g. also the bytes required to store the value of our string) ?

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

The object representation corresponds to the first part. For objects that are not trivially copiable, the object representation is not self sufficient (i.e. in our example, the bytes stored in the string are not necessarily part of the object representation).

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

The value representation corresponds to the second part (and would include the bytes required to store the value of the string).

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

In plain words, this means that the address of an object is the address of its representation, but the object representation may contain padding and may not be sufficient to hold every data that belongs to the object.

这篇关于如何根据c ++标准访问对象表示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆