Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is zero-length array allowed only if it's heap allocated?

Tags:

c++

arrays

I notice that it's not allowed to create non-heap allocated arrays of zero length.

// error: cannot allocate an array of constant length zero
char a[0];

I also notice that it's allowed to create heap allocated arrays of zero length.

// this is okay though
char *pa = new char[0];

I guess they're both guaranteed by the Standard (I don't have a copy of the Standard at hand). If so, why are they so different? Why not just allow a zero-length array on stack (or vice versa)?

like image 981
Eric Z Avatar asked Jul 28 '11 15:07

Eric Z


People also ask

Is array memory allocated on heap?

Dynamically allocated arrays are allocated on the heap at run time. The heap space can be assigned to global or local pointer variables that store the address of the allocated heap space (point to the first bucket).

Can we declare an array of size zero?

Zero-length array declarations are not allowed, even though some compilers offer them as extensions (typically as a pre-C99 implementation of flexible array members).

What is a heap allocated array?

Creating an array in the heapallocates a new array of 25 ints and stores a pointer to the first one into variable A. The size can be given by any expression that yields an integer. For example, if you already have an integer variable called n that currently holds 50, then. double* B = new double[n];

Does array use heap?

Storage of Arrays As discussed, the reference types in Java are stored in heap area. Since arrays are reference types (we can create them using the new keyword) these are also stored in heap area.


2 Answers

This is addressed in the following Sections of the C++ Standard.

3.7.3.1/2:

[32. The intent is to have operator new() implementable by calling malloc() or calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.]

And also,

5.3.4, paragraph 7

When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.


An Array of size 0 is not allowed by the C++ standard:

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."

In my understanding the rationale behind this seems to be the fact that C++ standard requires that every object must have an unique address(this is the very reason even an empty class object has size of 1).In the case of a non heap zero sized array, no objects need to be created, and hence no address is required to be given to it and hence no need of allowing it in first place.


As far as c is concerned, zero length arrays are allowed by the c standard, typically they are used to implement structures having a variable size by placing the zero length array at the end of the structure. If my memory serves my correct it is popularly called as C struct Hack.

like image 61
Alok Save Avatar answered Oct 23 '22 01:10

Alok Save


A 0 length array isn't very useful. When you're calculating the dimension, it can occur, and it is useful to not have to treat the case specially in your code. Outside of new, the dimension of the array must be a constant, not a calculated value, and if you know that the constant is 0, why define it?

At least, that's the rationale I've heard (from people who worked on it). I'm not totally convinced: it's not unusual in code to have to work with symbolic constants whose value isn't known (from a header file, or even the command line). So it probably would make sense to allows arrays of 0 elements. And at least one compiler in the past has allowed them, although I've forgotten which.

One frequent trick in C++ is to use such an array in a compile time assert, something like:

char dummyToTestSomeSpecificCondition[ condition ];

This will fail to compile if the condition is false, and will compile if it isn't. Except for that one compiler (if it still exists); I'll use something like:

char dummyToTestSomeSpecificCondition[ 2 * condition - 1 ];

, just in case.

like image 23
James Kanze Avatar answered Oct 23 '22 01:10

James Kanze