终止指向数组类型的结束指针 [英] Dereferencing one past the end pointer to array type

查看:140
本文介绍了终止指向数组类型的结束指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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_validint*的类型是从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屋!

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