* x与x [0]不同,因为x是指向未定义维数组的指针 [英] *x different from x[0] when x is a pointer to an array of undefined dimensions

查看:116
本文介绍了* x与x [0]不同,因为x是指向未定义维数组的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为a[0]等同于*a,但是随后我遇到了这段代码:

I've thought that a[0] is equivalent to *a, but then I came across this piece of code:

int arr[] = {1, 2, 3};
int (* a)[] = &arr;
printf("%d", (*a)[2]); // compiles
printf("%d", a[0][2]); // errors out

有一个指向未指定大小的数组的指针.第一个表达式可以很好地编译,而第二个表达式的结果是

There is a pointer to an array of unspecified size. The first expression compiles nicely, yet the second one results in

test.c:8:21: error: invalid use of array with unspecified bounds
     printf("%d", a[0][2]);
                     ^

来自Clang的错误是

The error from Clang is

error: subscript of pointer to incomplete type 'int []'

以及MSVC v19.10

and from MSVC v19.10

error C2036: 'int (*)[0]': unknown size


为什么a[0]不等同于*a?


Why isn't a[0] equivalent to *a?

推荐答案

2不是严格等效的. a[0]完全等同于*(a + 0)( C11 6.5. 2.1p2 ).

The 2 are not strictly equivalent. a[0] is exactly equivalent to *(a + 0) (C11 6.5.2.1p2).

对于* C11 6.5.3.2p2

  1. 一元*运算符的操作数应具有指针类型.
  1. The operand of the unary * operator shall have pointer type.

int (*)[]是;取消引用(*a)的结果是int [],它衰减为int *,然后用[2]进行索引,结果为3.

which int (*)[] is; the result of dereference (*a) is int [], which decays to int *, which is then indexed with [2], which results in 3.

但是a[0][2]等效于(*(a + 0))[2],在这里首先应用二进制+运算符的规则! C11 6.5.6p2 表示

However a[0][2] is equivalent to (*(a + 0))[2], and here the rules of binary + operator apply first! C11 6.5.6p2 says that

约束

  1. 另外,两个操作数都应具有算术类型,或一个操作数应是指向完整对象类型的指针,而另一个操作数应具有整数类型. (递增等于添加1.)
  1. For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

0具有整数类型,而a是指针,但它不是指向完整对象类型的指针,这意味着它与约束不匹配.

0 has an integer type, and a is a pointer, but it is not a pointer to a complete object type, which means it does not match the constraints.

由于此文本出现在约束"部分中,因此合格的编译器必须将其诊断为约束违规.与往常一样,符合标准的实现可能仍会正确翻译无效的程序,但至少GCC似乎完全拒绝了此操作并显示一条错误消息.

Since this text occurs in the constraints section, a conforming compiler must diagnose this as constraint violation. As always, a conforming implementation may still correctly translate an invalid program, but at least GCC seems to reject this outright with an error message.

这篇关于* x与x [0]不同,因为x是指向未定义维数组的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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