login
Header Space

 
 

Zero-length array to provide an elegant link

May 18, 2008 - 11:22am
Submitted by Eus on May 18, 2008 - 11:22am.

Consider the following struct and program:

#include <stdio.h>
#include <stdlib.h>

struct fix_data
{
	char data [5];
	unsigned char optional_part [0];
} __attribute__ ((packed));

int main (int argc, char **argv, char **envp)
{
	char buffer [10] = "Name\0emaN\0";
	int i = 0;
	struct fix_data *ptr = (struct fix_data *) buffer;

	printf ("ptr->data is %s\n", ptr->data);
	printf ("ptr->optional_part is %s\n", ptr->optional_part);

	exit (EXIT_SUCCESS);
}

The optional_part field function as a pointer to the next optional part that optional_part can point properly if the optional part really does exist.

Whereas, the following struct is intended to access an optional part in a separate memory location because you have to initialize the
optional_part field with the address of the separate memory location:

struct fix_data
{
	char data [5];
	unsigned char *optional_part;
} __attribute__ ((packed));

When you know that the optional part always follows the fixed part, the use of unsigned char *optional_part will just waste 4 bytes of memory space in 32-bit machines. That is why the special construct of declaring an array of size 0 is permitted to do this very thing: it tells the compiler that the array name points to the memory address after the last member, which is just before the array, of the struct.

Note that declaring an array of size 0 does not take up a space in the memory at all. So, the first construct of the struct has a size of 5 bytes, whereas the second construct has a size of 9 bytes in 32-bit machines.

I spotted this technique in the networking part of Linux kernel 2.6.21.5.

Zero-length array is an extension to the C programming language that GCC (GNU Compiler Collection) provides. So, if you are not using GCC, this may not work for you.

Archive: All about C Programming

speck-geostationary