42

Today I incidentally defined a two dimensional array with the size of one dimension being 0, however my compiler did not complain. I found the following which states that this is legal, at least in the case of gcc:

6.17 Arrays of Length Zero

However, I have two questions on this usage:

First, is this considered as good programming practice? If so, then when should we use it in real world?

Second, the array I defined was two dimensional, with 0 size for one dimension. Is this the same as the one dimensional case? For example,

int s[0]
int s[0][100]
int s[100][0]

Are they all the same in the memory and for the compiler?

EDIT: Reply to Greg: The compiler I am using is gcc 4.4.5. My intention for this problem is not compiler-dependent, however if there are any compiler specific quirks that would be helpful too:)

Thanks in advance!

zw324
  • 26,764
  • 16
  • 85
  • 118
  • Given that you have referenced the compiler in your question, it would help to provide information on the particular compiler you are concerned about. – Greg May 30 '11 at 19:28
  • 1
    Check this http://stackoverflow.com/questions/295027/array-of-zero-length – vasin May 30 '11 at 19:30
  • Note that with C++11, the `std::array` type [may have a size of 0](http://en.cppreference.com/w/cpp/container/array) (but normal arrays must still have at least one element). – Cameron Aug 24 '13 at 19:02
  • 2
    @JimFell don't disagree that 1) these are dupes and 2) the other question is more popular, but this comes about one year earlier - I am genuinely curious why it isn't the other way around? – zw324 May 17 '18 at 03:34

4 Answers4

38

In C++ it is illegal to declare an array of zero length. As such it is not normally considered a good practice as you are tying your code to a particular compiler extension. Many uses of dynamically sized arrays are better replaced with a container class such as std::vector.

ISO/IEC 14882:2003 8.3.4/1:

If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero.

However, you can dynamically allocate an array of zero length with new[].

ISO/IEC 14882:2003 5.3.4/6:

The expression in a direct-new-declarator shall have integral or enumeration type (3.9.1) with a non-negative value.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 1
    Charles couldn't understand the you can dynamically allocate an array of zero length, can you elaborate more on this. – Krishna Oza Jan 09 '15 at 14:46
  • 3
    @Krishna_Oza You can do this: `int *x = new int[0];` and it will return a pointer, but dereferencing it is undefined, since there is no possible reason to do so. The compiler could make dereferencing it do anything including crashing your program. – smead Feb 26 '16 at 05:27
4

I ran this program at ideone.com

#include <iostream>

int main()
{
    int a[0];
    int b[0][100];
    int c[100][0];

    std::cout << "sizeof(a) = " << sizeof(a) << std::endl;
    std::cout << "sizeof(b) = " << sizeof(b) << std::endl;
    std::cout << "sizeof(c) = " << sizeof(c) << std::endl;

    return 0;
}

It gave the size of all the variables as 0.

sizeof(a) = 0
sizeof(b) = 0
sizeof(c) = 0

So in the above example, no memory is allocated for a, b or c.

Node
  • 3,443
  • 16
  • 18
  • In answer can you add what compiler it was executed on, since the link you specified doesn't show the code. – Krishna Oza Jan 09 '15 at 14:48
  • @Krishna_Oza ideone.com uses gcc 5.1 as of 2015-10-20, which is one of the few compilers that supports empty arrays (which I've found rather convenient for generic testing when passing arrays of different sizes to functions, including emptiness as a valid test case). – Dwayne Robinson Oct 20 '15 at 08:38
2

Compiling your example with gcc, all three of them have sizeof 0, so I would assume that all of them are treated equally by the compiler.

Kanopus
  • 764
  • 5
  • 8
  • 1
    And that would be a compiler *bug*, not a vendor extension. C++ requires that all objects must have a size of at least one byte, so they get unique addresses. – Ben Voigt May 30 '11 at 19:45
  • @Ben Voigt: it's not a bug in the sense that gcc explicitly allows for zero length arrays, as shown in the link provided by the original poster. – Kanopus May 30 '11 at 19:57
  • It is a bug. Vendors have a lot of leeway in accepting code that the standard doesn't define behavior for, but when they do, they still need to follow whatever standard rules apply. The standard requires that every object have a unique address and a strictly positive size. subobjects need an address distinct from every object that is not a parent. – Ben Voigt May 30 '11 at 20:50
  • 3
    @Ben Voigt: you're right, but I would still define it as an extension and not a bug. This is my reasoning: for every case that an array has 1+ elements, gcc follows the standard by giving each object a distinct address. In the case of a zero sized array, no objects are created, and no address is required to be given, hence it falls (in my opinion) outside of the standard's description of an array, becoming a valid extension of the language. In other words, a zero sized array is not an array, but something else (an extension). – Kanopus May 30 '11 at 21:06
  • 1
    I agree with @Kanopus. The standard says this about `sizeof`. "When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element." When you choose to extend the standard you often have to break something. – CB Bailey May 30 '11 at 21:22
  • I second that agreement with @Kanopus, and would regard such an extension as useful. An interesting question, though, would be whether one should be allowed to define a size-zero array *type*. My inclination would be not. – supercat Jan 13 '12 at 23:35
  • VS2010 compiler throws error for arrays defined with zero as size `error C2466: cannot allocate an array of constant size 0` – Krishna Oza Jan 09 '15 at 14:50
2

Your link explains everything. They are used as last field in a struct when the length of struct is not known at compile time. If you try using them on stack or in a middle of other declarations you will end up overwriting next elements.

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65