取消引用一个超过指向数组类型的结束指针

Fra*_*eux 3 c++ arrays dereference language-lawyer

在c ++中是否已经很好地定义了一个指向数组类型的一个过去的指针?

请考虑以下代码:

#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));
}
Run Code Online (Sandbox Code Playgroud)

常识是,取消引用一个过去的指针是未定义的行为.但是,对于指向数组类型的指针,这是否适用?

这似乎是合理的,这应该是有效的,因为*my_past_end完全可以利用指针算法来解决,并产生一个指向数组中的第一个元素在那里,这恰好也是一个有效的,过去最末端int*的原始数组my_array.

但是,查看它的另一种方法*my_past_end是生成对不存在的数组的引用,该数组隐式转换为int*.这个参考对我来说似乎有问题.

对于上下文,我的问题是由这个问题引起的,特别是对这个答案的评论.

编辑:这个问题不是重复的通过下标获取一个过去的结束数组元素的地址:法律是否符合C++标准?我问的是问题中解释的规则是否也适用于指向数组类型的指针.

编辑2:删除auto以明确表示my_array_ptr不是int*.

Bar*_*rry 7

这是CWG 232.这个问题似乎主要是关于取消引用空指针,但它基本上是关于简单地取消引用不指向对象的东西意味着什么.关于这种情况没有明确的语言规则.

该问题的一个例子是:

同样,只要不使用该值,就应该允许取消引用指向数组末尾的指针:

char a[10];
char *b = &a[10];   // equivalent to "char *b = &*(a+10);"
Run Code Online (Sandbox Code Playgroud)

这两种情况在实际代码中经常出现,应该允许它们.

这与OP(a[10]上述表达式的一部分)基本相同,只是使用char而不是使用数组类型.

常识是,取消引用一个过去的指针是未定义的行为.但是,对于指向数组类型的指针,这是否适用?

基于它是什么类型的指针,规则没有区别.my_past_end是一个过去的结束指针,所以它是否取消引用它不是它指向一个数组而不是任何其他类型的事实的函数.


虽然类型is_this_validint*后者从一个初始化int(&)[3](数组到指针的衰减),因此这里没有什么真正从内存中读取-这是无关紧要的语言规则的工作方式.my_past_end是一个指针,其值超过了对象的末尾,这是唯一重要的事情.

  • 那么这是未定的行为吗? (2认同)