终止指向数组类型的结束指针 [英] Dereferencing one past the end pointer to array type
问题描述
在c ++中是否可以很好地定义将一个过去的指针取消引用到数组类型?
Is it well defined in c++ to dereference a one-past-the-end pointer to an array type?
考虑以下代码:
#include <cassert>
#include <iterator>
int main()
{
// An array of ints
int my_array[] = { 1, 2, 3 };
// Pointer to the array
using array_ptr_t = int(*)[3];
array_ptr_t my_array_ptr = &my_array;
// Pointer one-past-the-end of the array
array_ptr_t my_past_end = my_array_ptr + 1;
// Is this valid?
auto is_this_valid = *my_past_end;
// Seems to yield one-past-the-end of my_array
assert(is_this_valid == std::end(my_array));
}
通常的看法是,取消引用过去的指针是一种不确定的行为.但是,这是否适用于指向数组类型的指针?
Common wisdom is that it's undefined behavior to dereference a one-past-the-end pointer. However, does this hold true for pointers to array types?
这应该是合理的,因为*my_past_end
可以完全用指针算法解决,并产生一个指向将要存在的数组中第一个元素的指针,原始数组my_array
的有效的最后一个int*
.
It seems reasonable that this should be valid since *my_past_end
can be solved purely with pointer arithmetic and yields a pointer to the first element in the array that would be there, which happens to also be a valid one-past-the-end int*
for the original array my_array
.
但是,另一种查看方式是*my_past_end
生成对不存在的数组的引用,该引用隐式转换为int*
.这种参考对我来说似乎是个问题.
However, another way of looking at it is that *my_past_end
is producing a reference to an array that doesn't exist, which implicitly converts to an int*
. That reference seems problematic to me.
For context, my question was brought on by this question, specifically the comments to this answer.
Edit : This question is not a duplicate of Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not? I'm asking if the rule explained in the question also apply for pointers pointing to an array type.
删除了auto
以明确表示my_array_ptr
不是int*
.
Edit 2 : Removed auto
to make explicit that my_array_ptr
is not a int*
.
推荐答案
这是 CWG 232 .这个问题似乎主要与取消引用空指针有关,但从根本上讲与简单取消引用未指向对象的含义有关.对于这种情况,没有明确的语言规则.
This is CWG 232. That issue might seem like it's mainly about dereferencing a null pointer but it's fundamentally about what it means to simply dereference something that doesn't point to an object. There is no explicit language rule about this case.
问题中的一个例子是:
类似地,只要不使用该值,就应允许取消引用指向数组末尾的指针:
Similarly, dereferencing a pointer to the end of an array should be allowed as long as the value is not used:
char a[10];
char *b = &a[10]; // equivalent to "char *b = &*(a+10);"
这两种情况在实际代码中经常出现,应予以允许.
Both cases come up often enough in real code that they should be allowed.
除了使用char
而不是数组类型外,这与OP(上述表达式的a[10]
部分)基本上相同.
This is basically the same thing as OP (the a[10]
part of the above expression), except using char
instead of an array type.
通常的看法是,取消引用过去的指针是一种不确定的行为.但是,这是否适用于指向数组类型的指针?
Common wisdom is that it's undefined behavior to dereference a one-past-the-end pointer. However, does this hold true for pointers to array types?
基于哪种指针,规则没有区别. my_past_end
是一个过去的指针,因此是否用UB对其进行取消引用并不取决于它指向数组而不是其他类型的事实.
There is no difference in the rules based on what kind of pointer it is. my_past_end
is a past-the-end pointer, so whether it's UB to dereference it or not is not a function of the fact that it points to an array as opposed to any other kind of type.
is_this_valid
和int*
的类型是从int(&)[3]
初始化的(数组到指针的衰减),因此这里实际上没有从内存中读取任何内容,这与语言规则的工作方式无关紧要. my_past_end
是一个指针,其值是在对象的末尾 ,那是唯一重要的事情.
While the type of is_this_valid
an int*
which gets initialized from a int(&)[3]
(array-to-pointer decay), and thus nothing here actually reads from memory - that is immaterial to the way the language rules work. my_past_end
is a pointer whose value is past the end of an object, and that's the only thing that matters.
这篇关于终止指向数组类型的结束指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!