取消引用数组类型的结束指针 [英] 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.
这个问题不是 通过下标获取最后一个数组元素的地址:C++ 标准是否合法? 我在问规则是否在这个问题也适用于指向数组类型的指针.
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.
Edit 2 : 删除 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.
这与 OP 基本相同(上面表达式的 a[10]
部分),除了使用 char
而不是数组类型.
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(&)[3]
(array-to-指针衰减),因此这里实际上没有从内存中读取任何内容 - 这对语言规则的工作方式无关紧要.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屋!