What is the need of empty braces '{ }' at the end of array of structs?

CArraysStructLinux Kernel

C Problem Overview


I hit some [tag:c] code in Linux kernel:

static struct ctl_table ip_ct_sysctl_table[] = {
	{
		.procname	= "ip_conntrack_max",
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
	},
    // ...
	{
		.procname	= "ip_conntrack_log_invalid",
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= &log_invalid_proto_min,
		.extra2		= &log_invalid_proto_max,
	},
	{ }
};

Here an array of structs ends with { }. For what purpose was it added?
By the way, a bit above this code there is another array of structs, but without empty braces at the end.

When should I use empty braces at the end of an array of structs?

C Solutions


Solution 1 - C

This particular change was part of the sysctl net: Remove unused binary sysctl code commit by Eric W. Biederman, changing the initialization of the last element of the ip_ct_sysctl_table array from {0} to {} (and performs similar changes to many other array initializations).

The {0} pattern seems to have been around for much longer though, and both {0} or {} final element-initialization is commonly (in the Linux source code) explicitly referred to as Terminating entry, so it is likely a pattern present to allow consuming these arrays without knowing their lengths, terminating consumption when hitting the zero-initialized terminating entry. E.g. for the similar arrays in sound/aoa/fabrics/snd-aoa-fabric-layout.c the intent of the zero-initialization is even explicitly mentioned in a comment, e.g.:

> static struct codec_connection toonie_connections[] = { > { > .connected = CC_SPEAKERS | CC_HEADPHONE, > .codec_bit = 0, > }, > {} /* terminate array by .connected == 0 */ > };

Solution 2 - C

You're probably familiar with zero-terminated strings. ctl_table ip_ct_sysctl_table[] is a zero-terminated array, i.e. the last array entry has all-zero members.

Solution 3 - C

> What is the need of empty braces '{ }' at the end of array of structs?

To be clear: the "empty braces '{ }' at the end of array of structs" is not needed to satisfy C syntax requirements.

> When should I use empty braces at the end of an array of structs?

When code wants a sentinel value.

It is sometimes useful for the program to have a final array element of all zeros - certainly to detect the end. The need comes from the application's use of array ctl_table ip_ct_sysctl_table[], not from a C language need.

Solution 4 - C

It's one zero initialized element at the end of the array in order to increase the number of elements of the array by one.

Consider this small demo:

#include <stdio.h>

struct Test
{
  int x;
  int y;
} arr[] =
{
	{1,2},
	{3,4},
//	{}
};

int main(void) {
	printf("%zu\n", sizeof(arr) / sizeof(arr[0]));
	return 0;
}

The size of the arr array will change if you uncomment the {} at the end of the array initialisation list.

Outputs:

With // {} (array has 2 elements)

2

With {} (array has 3 elements)

3

Further explanation:

The ip_ct_sysctl_table array is only used at one place, that is here:

in->ctl_table = kmemdup(ip_ct_sysctl_table,
				sizeof(ip_ct_sysctl_table),
				GFP_KERNEL);

The extra {} increases the total size ip_ct_sysctl_table.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNK-cellView Question on Stackoverflow
Solution 1 - CdfribView Answer on Stackoverflow
Solution 2 - CMSaltersView Answer on Stackoverflow
Solution 3 - Cchux - Reinstate MonicaView Answer on Stackoverflow
Solution 4 - CJabberwockyView Answer on Stackoverflow