8
#include <stdio.h>
int main()
{
    int a[0],b[4][0];
    printf("%d %d ",sizeof(a),sizeof(b));
}
//output
0 0

what is the significance of a[0] , why also 2d array of size 0 is allowed?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Utkarsh Srivastav
  • 3,105
  • 7
  • 34
  • 53

3 Answers3

9

Neither C nor C++ allow arrays of zero length, so your program is ill-formed.

(E.g. C++11, 8.3.4/1: "[the array size] shall be greater than zero".)

(As one point of rationale: An array of zero length would be tricky and confusing to reconcile with the requirement that each object have a unique address.)

As @sidyll points out, zero-length arrays are available as an extension in GCC.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • it is not giving error in gcc compiler ubuntu 10.04 – Utkarsh Srivastav Dec 24 '11 at 16:18
  • 4
    @user1044137: There are many, many, many ways to write both C and C++ programs that are ill-formed and for which you receive no diagnostic. For that matter, my GCC says `warning: ISO C++ forbids zero-size array`. You should always enable all warnings. – Kerrek SB Dec 24 '11 at 16:20
  • 1
    Why are you compiling a **C** program from a **C** question with a **C++** compiler and posting a **C++** standard excerpt? – sidyll Dec 24 '11 at 16:28
  • @sidyll: This used to be tagged C++; check the edit log. – Kerrek SB Dec 24 '11 at 16:29
  • @sidyll: GCC also says `warning: ISO C forbids zero-size array` for all three versions of C. – Kerrek SB Dec 24 '11 at 16:30
  • I know it was C++, but the incorrect usage of this dirty language to refer to C makes me "one of these days I'm going to cut you into little pieces, C++". Oh man this drives me crazy. Ok, sorry. Back to the business: Strangely enough I didn't receive any warning, neither in Clang nor GCC – sidyll Dec 24 '11 at 16:51
  • @sidyll: You need the `-pedantic` option to enable strict conformance checks. For new projects I would recommend `-W -Wall -Wextra -Wwrite-strings -pedantic`; probably adorned with `-std=c99`. Ditto for C++, but without the "write-strings" (which is automatic). – Kerrek SB Dec 24 '11 at 16:59
  • 1
    I would recommend some `-Wno-...` options after `-Wall -Wextra`. gcc includes some nonsensical stuff that spuriously triggers all the time on correct programs and even forces you to shun best-practices in certain cases if you want to shut up the warnings (e.g. you cannot use the universal zero-initializer for opaque types, `{0}`). – R.. GitHub STOP HELPING ICE Dec 24 '11 at 18:00
3

You'll find your answer in The GCC manual

If you are using c99

  • Flexible array members are written as contents[] without the 0.
  • Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
  • Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
  • A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.

And of course, how they can be useful:

Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object:

struct line {
   int length;
   char contents[0];
 };

struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;
Shog9
  • 156,901
  • 35
  • 231
  • 235
Anil Arya
  • 3,100
  • 7
  • 43
  • 69
1

There is not much use as given in your example, but zero size arrays were frequently used in structures where the last element was dynamically sized:

struct {
     int    some_fixed_data [N_FIXED];
     float  more_fixed_size_data [F_FIXED];
     int    n_variable_elements;
     long   variable_elements [0];  // allocated based on item above
} s;

int curlen = sizeof s + sizeof long * s.n_variable_elements;

The use of a zero length array is:

1) variable_elements has an address (despite someone's answer)
2) it also has array semantics
3) computing the dynamic size of the array is simplified

Unfortunately, some compilers (MSC) would throw a hissy fit over such a construction and force a lesser, appeasing, technically incorrect reformulation:

struct {
     int    some_fixed_data [N_FIXED];
     float  more_fixed_size_data [F_FIXED];
     int    n_variable_elements;
     long   variable_elements [1];  // allocated based on item above
} s;

int curlen = sizeof s + sizeof long + (s.n_variable_elements - 1);

Think of a zero size array as a placeholder. There is little need to do that anymore, unless you are forced to use C which is the case on many embedded environments.

wallyk
  • 56,922
  • 16
  • 83
  • 148