##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# Array declaration

From cppreference.com
< cpp‎ | language

Declares an object of array type.

### [edit] Syntax

An array declaration is any simple declaration whose declarator has the form

noptr-declarator `[` constexpr(optional) `]` attr(optional) | (1) |

noptr-declarator | - | any valid declarator, but if it begins with *, &, or &&, it has to be surrounded by parentheses.
attr(C++11) | - | optional list of attributes
constexpr | - | a converted constant expression of type std::size_t, which evaluates to a value greater than zero

A declaration of the form T a[N];, declares `a` as an array object that consists of `N` contiguously allocated objects of type `T`. The elements of an array are numbered `0...N-1`, and may be accessed with the member access operator [], as in a[0] ... a[N-1].

Arrays can be constructed from any fundamental type (except void), pointers, pointers to members, classes, enumerations, or from other arrays (in which case the array is said to be multi-dimensional). There are no arrays of references, arrays of functions, or arrays of incomplete types.

Applying cv-qualifiers to an array type (through typedef or template type manipulation) applies the qualifiers to the element type, but any array type whose elements are of cv-qualified type is considered to have the same cv-qualification.

    // arr1 and arr2 have the same const-qualified type "array of 5 const char"
    typedef const char CC;
    CC arr1[5] = {};
    typedef char CA[5];
    const CA arr2 = {};

#### [edit] Assignment

Objects of array type cannot be modified: even though they are lvalues (e.g. an address of array can be taken), they cannot appear on the left hand side of an assignment operator:

    int a[3] = {1,2,3}, b[3] = {4,5,6};
    int (*p)[3] = &a; // okay, address of a can be taken
    a = b;            // error, a is an array
    struct { int c[3]; } s1, s2 = {3,4,5};
    s1 = s2; // okay: implicity-defined copy assignment operator
             // can assign data members of array type

#### [edit] Array to pointer decay

There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are:

Run this code

    #include <iostream>
    #include <numeric>
    #include <iterator>

    void g(int (&a)[3])
    {
        std::cout << a[0] << '\n';
    }
    void f(int* p) {
        std::cout << *p << '\n';
    }

    int main()
    {
        int a[3] = {1,2,3};
        int* p = a;

        std::cout << sizeof a << '\n'  // prints size of array
                  << sizeof p << '\n'; // prints size of a pointer

        // where arrays are acceptable, but pointers aren't, only arrays may be used
        g(a); // OK: function takes an array by reference
    //  g(p); // Error

        for(int n: a)              // OK: arrays can be used in range for loops
            std::cout << n << ' '; // prints elements of the array
    //    for(int n: p)            // Error
    //        std::cout << n << ' ';

        std::iota(std::begin(a), std::end(a), 7); // OK: begin/end take arrays
    //  std::iota(std::begin(p), std::end(p), 7); // Error

        // where pointers are acceptable, but arrays aren't, both may be used:
        f(a); // OK: function takes a pointer
        f(p); // OK: function takes a pointer

        std::cout << *a << '\n' // prints the first element
                  << *p << '\n' // same
                  << *(a+1) << ' ' << a[1] << '\n' // prints the second
                  << *(p+1) << ' ' << p[1] << '\n';
    }

#### [edit] Multidimensional arrays

When the element type of an array is another array, it is said that the array is multidimensional:

    // array of 2 arrays of 3 ints each
    int a[2][3] = {{1,2,3},  // can be viewed as a 2x3 matrix
                   {4,5,6}}; // with row-major layout

Note that when array-to-pointer conversion is applied, a multidimensional array is converted to a pointer to its first element, e.g., pointer to the first row:

    int a[2][3]; // 2x3 matrix
    int (*p1)[3] = a; // pointer to the first 3-element row
    int b[3][3][3]; // 3x3x3 cube
    int (*p2)[3][3] = a; // pointer to the first 3x3 plane

#### [edit] Arrays of unknown bound

If constexpr is omitted in the declaration of an array, the type declared is "array of unknown bound of T", which is a kind of incomplete type, except when used in a declaration with an aggregate initializer:

    extern int x[]; // the type of x is "array of unknown bound of int"
    int a[] = {1,2,3}; // the type of a is "array of 3 int"

#### [edit] Array rvalues

An array rvalue expression may be formed by accessing an array member of a class rvalue or by using an identity template to construct an array temporary directly:

Run this code

    #include <iostream>
    #include <type_traits>

    void f(int (&&x)[2][3])
    {
        std::cout << sizeof x << '\n';
    }

    struct X {
        int i[2][3];
    } x;

    template<typename T> using identity = T;

    int main()
    {
        std::cout << sizeof X().i << '\n'; // size of the array
        f(X().i); // OK, binds to rvalue
    //  f(x.i);   // Error: cannot bind to lvalue

        f(identity<int[][3]>{{1,2,3},{4,5,6}}); // OK, binds to rvalue
    }

Output:

    24
    24
    24

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/array&oldid=71441"