自C ++ 17起,具有正确地址和类型的指针仍然始终是有效的指针吗? [英] Is a pointer with the right address and type still always a valid pointer since C++17?

查看:62
本文介绍了自C ++ 17起,具有正确地址和类型的指针仍然始终是有效的指针吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(参考在C ++ 17标准之前, [basic.compound]/3 :

Before the C++17 standard, the following sentence was included in [basic.compound]/3:

如果类型T的对象位于地址A,则无论其值如何获得,都将以其值为地址A的cv T *类型的指针指向该对象.

If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained.

但是从C ++ 17开始,此句子已已删除.

But since C++17, this sentence has been removed.

例如,我相信这句话使示例代码定义完整,并且自C ++ 17起,这是未定义的行为:

For example I believe that this sentence made this example code defined, and that since C++17 this is undefined behavior:

 alignas(int) unsigned char buffer[2*sizeof(int)];
 auto p1=new(buffer) int{};
 auto p2=new(p1+1) int{};
 *(p1+1)=10;

在C ++ 17之前,p1+1将地址保存为*p2并具有正确的类型,因此*(p1+1)是指向*p2的指针.在C ++ 17中,p1+1 过去的指针-end ,因此它不是对象的指针,而且我认为它是不可引用的.

Before C++17, p1+1 holds the address to *p2 and has the right type, so *(p1+1) is a pointer to *p2. In C++17 p1+1 is a pointer past-the-end, so it is not a pointer to object and I believe it is not dereferencable.

是对标准权利的这种修改的解释,还是有其他规则可以补偿被引句子的删除?

Is this interpretation of this modification of the standard right or are there other rules that compensate the deletion of the cited sentence?

推荐答案

是对标准权利的这种修改的解释,还是有其他规则可以补偿该被引句子的删除?

Is this interpretation of this modification of the standard right or are there other rules that compensate the deletion of this cited sentence?

是的,这种解释是正确的.末尾的指针不能简单地转换为恰好指向该地址的另一个指针值.

Yes, this interpretation is correct. A pointer past the end isn't simply convertible to another pointer value that happens to point to that address.

新的 [basic.compound]/3 说:

每个指针类型的值是以下值之一:
(3.1) 指向对象或函数的指针(据说该指针指向该对象或函数),或者
(3.2) 一个超出对象末尾的指针([expr.add]),或者

Every value of pointer type is one of the following:
(3.1) a pointer to an object or function (the pointer is said to point to the object or function), or
(3.2) a pointer past the end of an object ([expr.add]), or

这些是互斥的. p1+1是末尾的指针,而不是指向对象的指针. p1+1指向在p1处的size-1数组的假设x[1],而不是p2.这两个对象不是指针可互换的.

Those are mutually exclusive. p1+1 is a pointer past the end, not a pointer to an object. p1+1 points to a hypothetical x[1] of a size-1 array at p1, not to p2. Those two objects are not pointer-interconvertible.

我们还有非规范性注释:

We also have the non-normative note:

[注意:超出对象末尾的指针([expr.add])不被认为指向该对象类型的无关对象,该对象可能位于该地址. [...]

[ Note: A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object's type that might be located at that address. [...]

阐明了意图.

作为T.C.指出许多评论( CWG 2182 P0593R1 (特别是第1.3节)

As T.C. points out in numerous comments (notably this one), this is really a special case of the problem that comes with trying to implement std::vector - which is that [v.data(), v.data() + v.size()) needs to be a valid range and yet vector doesn't create an array object, so the only defined pointer arithmetic would be going from any given object in the vector to past-the-end of its hypothetical one-size array. Fore more resources, see CWG 2182, this std discussion, and two revisions of a paper on the subject: P0593R0 and P0593R1 (section 1.3 specifically).

这篇关于自C ++ 17起,具有正确地址和类型的指针仍然始终是有效的指针吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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