Search code examples
c++arraysc++11incomplete-type

Is int arr[ ] valid C++?


I am trying to understand if writing int arr[]; is valid in C++. So take for example:

int a[]; //is this valid?
extern int b[];//is this valid?

int (*ptrB)[]; //is this valid?
struct Name
{
    int k[]; //is this valid?
};
void func()
{
    ptrB++; //is this valid?
}
int a[10];
int b[10];
void bar()
{
    ptrB = &b;//is this valid?
    ptrB++; //is this valid?
}
int main()
{
    int c[];//is this valid?
    extern int d[]; //is this valid?
}

int c[10];
int d[10];

I have read some comments on SO stating that int p[]; is not valid C++. So I wanted to know in what situations is this valid/invalid. For that I wrote the above snippet and want to understand through this example.


Solution

  • Let us look at each of the cases.

    Case 1

    Here we have the statement

    int a[]; //this is a definition so size must be known
    

    This is not valid.

    Case 2

    Here we have the statement:

    extern int b[];//this is a declaration that is not a definition
    

    This is valid. Here the type of b is incomplete. Also, b has external linkage.

    Case 3

    Here we have:

    int (*ptrB)[]; 
    

    This is valid. We say that ptrB is a pointer to an incomplete type.

    Case 4

    Here we have:

    struct Name
    {
        int k[]; //NOT VALID
    };
    

    This is not valid as from cppreference:

    Any of the following contexts requires type T to be complete:

    • declaration of a non-static class data member of type T;

    Case 5

    Here we have:

    void func()
    {
        ptrB++; //NOT VALID
    }
    

    This is not valid as from postfix increment's documentation:

    The operand expr of a built-in postfix increment or decrement operator must be a modifiable (non-const) lvalue of non-boolean (since C++17) arithmetic type or pointer to completely-defined object type.

    Case 6

    Here we have:

    void bar()
    {
        ptrB = &b;//NOT VALID
    }
    

    This is not valid as from cppreference:

    The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points ("array of unknown bound of T" and "array of N T") are different types.

    Case 7

    Here we have:

    void bar()
    {
        ptrB++; //NOT VALID
    

    This is not valid as from cppreferene:

    The type of a pointer to array of unknown bound, or to a type defined by a typedef declaration to be an array of unknown bound, cannot be completed.

    So we will get the same error as in case 5.

    Case 8

    Here we have:

    int main()
    {
        int c[]; 
    }
    

    This is not valid since this is a definition and so size must be known.

    Case 9

    Here we have:

    int main()
    {
        extern int d[]; non-defining declaration
    }
    

    This is valid. d has external linkage.