This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Zero-length arrays


In article <718D38CAB6E0D011B2C90060970C28A5642562@EXCHANGESERVER> you write:
>
>>  Aren't they only allowed at the *end* of structs ?
>>
>>That's what the documentation implies (though it's less clear that it
>>could be) but there's no code to check for it.
>>
>>Note that zero-length arrays should be allowed anywhere, but everywhere but
>>the end they really *are* zero length and aren't extendable.
>
>  I can't see the point in a genuine 0-length array ?

Actually, they do occur quite naturally in certain circumstances.

A plain

	int array[0];

is obviously completely useless. But a

	struct randomstruct {
		int my_value;
		struct randomstruct * others[NR_STRUCTS-1];
	}

construct (with the structures becoming a hard-wired pointer-network) is
not necessarily silly. 

And I think you can see how the 0-length array case is a natural
degenerate case of the above: if the network has only one node, the
"others" array basically disappears.

Yes, the Linux kernel has things like this.  It cleans code up a LOT
when you don't have to special-case stuff (with traditional C rules,
you'd have to hide the "others" field inside a "#if NR_STRUCTS > 1 /
#endif" thing, and then you'd need to add similar constructs when you
actually access the thing etc, instead of just letting the compiler make
the code magically go away. 

So you can use

	sum = p->my_value;
	for (i = 0; i < NR_STRUCTS-1; i++)
		sum += p->others[i];

and not worry about whether "others" will get a syntax error or not.
Things like that make for cleaner and more understandable code, and lets
the compiler automatically optimize away the code that becomes void for
the degenerate cases.

Imagine, for example, that you had a (completely hypothetical example,
not) source tree that had to worry about multiple CPU's, but where the
special case of just supporting one CPU fell out as a degenerate case of
NUM_CPUS == 1.  Imagine that the source code looks much nicer without
#ifdef CONFIG_SMP all over the place. 

Things like that.

And no, it's not what ANSI means with their unspecified array (which has
a different syntax: a unspecified array is specified the way strings
have always been specified, with a simple array[] - no zero anywhere).
But it _is_ a documented and quite useful extension.

(I never understood why C had that silly "you can't have a zero-length
array" rule. Even if there were no real reasons to use them, it still
has a clear and unambiguous conceptual meaning)

		Linus

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]