6

In C, array subscription: a[b] is merely the syntactic sugar equivalent of dereferencing after pointer arithmetic: *(a+b) (as explained, say, here).

How is array subscription interpreted in C++, for base types? (Not for classes, for which we have overload semantics)? And, more specifically, what type does C++ expect to appear as the subscript? Is it a ptrdiff_t?

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    C++ does the same thing C does for base types. – RichardPlunkett Dec 04 '13 at 14:53
  • I think the article you link to explains it well. For basic types, `a[b]` is valid if and only if `*(a + b)` is. So the valid types for `b` depend on the type of `a`, but basically any integer type is fine if `a` is a pointer-to-object type, or any pointer-to-object type if `a` is an integer type. What's the question, are you just asking for confirmation that answer is correct when it says, "C++ inherited this definition from C"? – Steve Jessop Dec 04 '13 at 14:54
  • I think it does the same thing for all data types...I can't think of a data type treated differently by c++ – Pandrei Dec 04 '13 at 14:54

2 Answers2

7

How is array subscription interpreted in C++,

In C++ E1[E2] is identical to *((E1)+(E2))

what type does C++ expect to appear as the subscript?

C++ expects a unscoped enumeration or integral type both items are covered in the draft C++ standard section 5.2.1 Subscripting paragraph 1 which says (emphasis mine):

A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “pointer to T” and the other shall have unscoped enumeration or integral type. The result is an lvalue of type “T.” The type “T” shall be a completely-defined object type.62 The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [ Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. —end note ]

As James points out, the wording One of the expressions shall have allows the pointer and subscript to be interchanged, for example:

#include <iostream>

int main()
{
    int arr[5] = {1, 2, 3, 4, 5 } ;

    std::cout << arr[2] << ":" << 2[arr] << std::endl ;
}

Using the alternative syntax 2[arr] is not recommended, most people won't know what this is doing it makes the code less readable and hence less maintainable.

which is similar to the relevant section in the draft C99 standard 6.5.2.1 Array subscripting paragraph 2 which says(emphasis mine):

A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
3

C++ is exactly the same as C in this respect. C++11 §5.2.1:

The expression E1[E2] is identical (by definition) to *((E1)+(E2))

NPE
  • 486,780
  • 108
  • 951
  • 1,012