1

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]);
                     ^

The error from Clang is

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

and from MSVC v19.10

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

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

Antti Haapala
  • 117,318
  • 21
  • 243
  • 279
  • While at this I found a "bug" (EEE anyone) in MSVC. Apparently msvc considers `int (*)[]` to be `int (*)[0]`... – Antti Haapala Dec 25 '18 at 08:07
  • @AnttiHaapala and is that taken from the first indexing? – Sourav Ghosh Dec 25 '18 at 08:09
  • @SouravGhosh [nope...](https://godbolt.org/z/MpwuNN) – Antti Haapala Dec 25 '18 at 08:15
  • D'oh and it is a duplicate :F - I thought I had done thorough search but couldn't find the duplicate except when searching for discussion on the MSVC bug. So I guess this is good to have here then. – Antti Haapala Dec 25 '18 at 08:23
  • By curiosity, why you do not delete your question being a duplicate in the same way you delete the ones written by other OP ? – bruno May 01 '19 at 16:05
  • @bruno https://meta.stackoverflow.com/a/265737/918959 - those few that I've deleted are such that no one would *actually* find help for their problem by googling them. There are actually *other* close reasons that equally apply to them but they're also low quality duplicates. – Antti Haapala May 01 '19 at 17:16
  • @bruno Likewise I ask you: why can't I see you often casting a close vote... – Antti Haapala May 01 '19 at 17:17
  • But I do close votes, what is the minimal value of often ^^ ? more seriously I do even I do not very like, it is not 'gentle' for the OP (not sure is the right word, my poor English) even needed for stackoverflow quality – bruno May 01 '19 at 17:18

1 Answers1

4

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

For *, C11 6.5.3.2p2 says that

  1. The operand of the unary * operator shall have pointer type.

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

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

Constraints

  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 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.

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.

Community
  • 1
  • 1
Antti Haapala
  • 117,318
  • 21
  • 243
  • 279