2

Example:

int main()
{
    int array[];
}

Is it just an uninitialized pointer? Or an array with a small default size?

Which compilers support this syntax, and why? I see this as a recipe for confusion.

Also mentioned here:

Can I declare an array in C without declaring its size and element?

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • 1
    When used as last element of a struct definition, this is called a flexible array member. In any other location like in your sample that should be illegal. – Gerhardh Apr 17 '23 at 09:01
  • 1
    You can't do this. It's not legal code and any sane compiler will show an error for this, like "unknown size". If it were legal, `array` would be an array of size zero which is pretty pointless. – Jabberwocky Apr 17 '23 at 09:01
  • 1
    Possibly related: [Is using flexible array members in C bad practice?](https://stackoverflow.com/q/246977/10871073) – Adrian Mole Apr 17 '23 at 09:02
  • "Is it just an uninitialized pointer?" How would that be? Arrays are very different from pointers. Whaterver that line means if a compiler accepts it, is not related to any pointer – Gerhardh Apr 17 '23 at 09:03
  • Have you actually *seen* this anywhere? Are you sure it was not a K&R-style function header, like `int main(argc, argv) int argc; char *argv[]; { /*code here*/ }`? – Ture Pålsson Apr 17 '23 at 09:35
  • 1
    I have seen something that resembles this (see linked question). I copied the syntax incorrectly, and so asked a wrong question. Now this wrong question has answers, so I won't change it. – anatolyg Apr 17 '23 at 10:22

5 Answers5

3

For this declaration to be valid, there needs to be an initializer list present:
int array[] = { ... };.

Otherwise the array is incomplete, C17 6.7.6.2:

If the size is not present, the array type is an incomplete type.

Incomplete array types at local scope are not valid declarations and a conforming compiler will raise a diagnostic message. Incomplete array types are only allowed in some special cases:

  • A function declaration may contain an incomplete array type since it gets adjusted to a pointer to the first element. After adjustment, the array should not have incomplete type (nor be of an array type with incomplete element type).

    void func (int array[]) is therefore valid and equivalent to void func (int* array).

  • The last member of a struct can be an incomplete array type, a so-called flexible array member.

  • As a file scope array declared outside any function, with its type completed later in the same translation unit or when it has external linkage (extern etc), referring to an array in another translation unit.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    Re “Incomplete array types are not valid declarations”: `int array[];` at file scope (not shown in the question) is a valid declaration of an object with an incomplete array time. – Eric Postpischil Apr 17 '23 at 11:35
  • 1
    @EricPostpischil The way this site works is that posts on SO answer the question posted by the OP. They do not answer a fictional question not posted by the OP. – Lundin Apr 17 '23 at 13:07
  • I did not complain that this answer does not answer a fictional question. I complain that this answer makes a false statement. – Eric Postpischil Apr 17 '23 at 13:15
  • @EricPostpischil I updated the post for the benefit of language lawyers (at the expense of beginners). I don't think it made the answer any better or easier to understand... – Lundin Apr 17 '23 at 14:02
2

As other answers indicate, the code is illegal in C in that context.

However, if the declaration includes initialization, then the array has proper size:

int array[] = {10, 20, 30}; // array has size 3

A special case is when the initialization is empty:

int array[] = {}; // array has size 0

In this case, the size of the array is 0. This is not allowed in C, but some compilers support this.

int main()
{
    int array[] = {};
    printf("%zu", sizeof(array));
}

Compiled by gcc: OK, prints 0

Compiled by gcc -pedantic: error: zero or negative size array

Compiled by MS Visual Studio: error: cannot allocate an array of constant size 0

A zero-size array is mostly useless; it provides the same functionality as flexible array member, but is non-standard — only supported for compatibility with some old code.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

The construct int array[]; as it appears in your code (in other words: as a stand-alone array) is illegal in C.

Supposing it were legal:

Q: Is it just an uninitialized pointer?

A: an array is not a pointer. If such a declaration were legal it would be an array of size zero. And if you'd assign array to a pointer, the pointer would point to a segment of memory of size 0. BTW latter is actually possible by using malloc(0), but that's another story.

Q: Is it an array with a small default size?

A: Not there are no default sizes in C. BTW what would that default size be?

Q: Which compilers support this syntax, and why?

A: AFAIK no sane C compiler supports this for a good reason.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Re “AFAIK no sane C compiler supports this for a good reason”: [GCC and Clang support this](https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html), although it is intended as a member of a variable-length object, not as a stand-alone array. – Eric Postpischil Apr 17 '23 at 11:56
  • @EricPostpischil I reworded the first sentence to make it clearer. – Jabberwocky Apr 17 '23 at 12:08
1

int array[]; declares array with an incomplete array type.

Inside a function (i.e. at block scope), a declaration of a variable that is not declared extern, and that has no initializer, but is declared with an incomplete array type is not allowed.

Outside a function (i.e. at file scope), a declaration of a variable that is not declared extern, and that has no initializer, but is declared with an incomplete array type is allowed as a tentative definition of the variable. If the variable's type is still incomplete at the end of translation unit (i.e. at the end of the current compilation), it will be implicitly initialized with the initializer {0} causing it to have one element (but its size cannot be measured with sizeof because the type is still incomplete at the point where sizeof is used).

Ian Abbott
  • 15,083
  • 19
  • 33
-1

I see this as a recipe for confusion

Which is exactly why this is not allowed by design in the language. So no compiler will support this. The array must be known in size either by providing a size in the array declaration, or by immediate initialization so the size can be derived.

https://en.cppreference.com/w/cpp/language/array#Arrays_of_unknown_bound

Evert_B
  • 193
  • 5
  • Re “So no compiler will support this”: [GCC and Clang support this](https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html), although it is intended as a member of a variable-length object, not as a stand-alone array. – Eric Postpischil Apr 17 '23 at 11:54
  • 1
    Re “Which is exactly why this is not allowed by design in the language”: The code is conforming code but not strictly conforming code. It is allowed in the language by the rules in C 2018 4 6 and 4 7. – Eric Postpischil Apr 17 '23 at 12:06
  • It is allowed in as a flexible array member as the last element of a struct. However, this is not relevant to the question which was asked. Is it worth mentioning? Yes. But as OP stated in his own question: "I see this as a recipe for confusion". To the original question the answer remains: it is not supported by a compiler and not allowed by the language standard. – Evert_B Apr 18 '23 at 09:48