2

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.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 2
    [Arrays of unknown bound](https://en.cppreference.com/w/cpp/language/array#Arrays_of_unknown_bound). – Some programmer dude Jan 08 '22 at 10:16
  • 1
    "I have read some comments on SO stating that int p[]; is not valid C++.": It is likely that these were specifically in reference to `int p[]` as a data member of a class. This is allowed in C as last member of a `struct` and called a _flexible array member_ there, but is not allowed in C++. Some compilers allow it in C++ mode as an extension anyway (if strict conformance flags aren't used). – user17732522 Jan 08 '22 at 10:23

1 Answers1

10

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.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Is case 4 valid C, however? https://stackoverflow.com/a/26183999/17635987 – kirjosieppo Jan 08 '22 at 11:13
  • 1
    @kirjosieppo In the link you posted, it is written that *"As a special case, the last element of a structure with **more than one** named member may have an incomplete array type..."* . So i am not 100% sure if case 4 is valid in `C` since it has only one member and in the quote it is written that "for more than one". I think case 4 is invalid in C according to the above quoted statement. – Jason Jan 08 '22 at 11:22
  • Type of b actually complete but is equivalent to a pointer. – Swift - Friday Pie May 06 '22 at 13:00
  • @Swift-FridayPie No, it is incomplete. To verify this you can use `sizeof`. See [demo1](https://onlinegdb.com/WVN_ACh5m) and [demo2](https://onlinegdb.com/lSPybaBj6). – Jason May 14 '22 at 08:15