您可以对指向另一个对象的char *进行算术运算吗 [英] Can you do arithmetic on a char* pointing at another object

查看:103
本文介绍了您可以对指向另一个对象的char *进行算术运算吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是读取平凡可复制对象字节的常用方法

Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
    consume(p[i]);

问题不在于严格混叠,char*允许为任何东西加上别名.问题出在 [expr.add]

当将具有整数类型的表达式添加到指针或从指针中减去时,结果将具有指针操作数的类型.如果表达式P指向具有n元素的数组对象x的元素x[i],则表达式P + JJ + P(其中J的值为j)指向(可能是假设的)x[i + j]元素,如果0 ≤ i + j ≤ n;否则,行为是不确定的.同样,如果0 ≤ i − j ≤ n,则表达式P - J指向(可能是假想的)元素x[i − j];否则,行为是不确定的.

假设元素指的是

为此,超出n个元素的数组x的最后一个元素的指针被认为等效于指向假设元素x[n]的指针

这就是说,仅当算术在指向数组的指针上并且结果仍在其范围内时,这才是合法的.

但是,这里显然没有char[sizeof(Object)],我们可以对该指针进行算术运算吗?

请注意,读取对象字节的合法解决方案是std::memcpy该对象.但是,如果这是仅 的解决方案,它就会问,如果您几乎不能对它做任何事情,为什么还要允许char*别名呢?

解决方案

根据引号,指针算法应合法. Object实例obj可以视为char[sizeof(Object)].因此,它是n个元素的数组(请注意nsizeof(Object)). Standard允许在此数组的边界内执行指针算术,并在此数组的边界外加上一个假设元素.这是由于

中的小于或等于符号

0≤i + j≤n

表达式.

从字面上看,reinterpret_cast<char*> (&obj) + sizeof(Object)很好,因为它指向假设元素a[j],其中j = sizeof(Object)且它小于或等于数组sizeof(Object)的大小. /p>

因此,答案是肯定的.

否则,数组的std::end将是UB.

This is a common way to read the bytes of an trivially copyable object

Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
    consume(p[i]);

The problem isn't with strict-aliasing, char* is allowed to alias anything. The problem is with this passage from [expr.add]

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i + j] if 0 ≤ i + j ≤ n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i − j] if 0 ≤ i − j ≤ n; otherwise, the behavior is undefined.

Where hypothetical element refers to

A pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical element x[n] for this purpose

Which is to say, it is only legal if the arithmetic is on a pointer pointing at an array, and the result is still within its range.

However, there is clearly no char[sizeof(Object)] here, can we do arithmetic on that pointer?

Note that a legal solution to reading bytes of an object is to std::memcpy the object. But if that is the only solution, it begs to ask, why allow char* aliasing if you can barely do anything with it?

解决方案

The pointer arithmetic should be legal according to the quotes. An Object instance obj can be viewed as char[sizeof(Object)]. So, it is an array of n elements (note that n is sizeof(Object)). Standard allows to do pointer arithmetic in bounds of this array plus one hypothetical element beyond the bounds of this array. This is due to less or equal sign in the

0 ≤ i + j ≤ n

expression.

Literally, reinterpret_cast<char*> (&obj) + sizeof(Object) is fine because it points to hypothetical element a[j], where j = sizeof(Object) and it is less or equal than size of the array, which is sizeof(Object).

So, the answer is yes.

Otherwise std::end for arrays would be UB.

这篇关于您可以对指向另一个对象的char *进行算术运算吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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