Why does such a struct contain two array fields containing only one element?

arrays, c, idioms, linux, struct

Solution

These fields are an optimization so Linux doesn't have to perform as many allocations for a typical process that has no more than `BITS_PER_LONG` open file descriptors.

The `close_on_exec_init` field provides the initial storage for `fdt->close_on_exec` when a `files_struct` is allocated. (See `dup_fd` in `fs/file.c`.)

Each bit of `fdt->close_on_exec` is set if the corresponding file descriptor has the “close-on-exec” flag set. Thus Linux only needs to allocate additional space for `fdt->close_on_exec` if the process has more open file descriptors than the number of bits in an `unsigned long`.

The `open_fds_init` field serves the same function for the `fdt->open_fds` field. The `fd_array` field serves the same function for the `fdt->fd` field. (Note that `fd_array` has a size of `BITS_PER_LONG`.)

The `close_on_exec_init` and `open_fds_init` fields formerly had type `struct embedded_fd_set`, but were changed to bare arrays in this commit. The commit message doesn't explain why the author chose to use one-element arrays instead of bare scalars. Perhaps the author (David Howells) simply wanted to avoid using the `&` operator.

Problem

Please Note: This question is not a duplicate of ( One element array in struct ) The following code is excerpted from the Linux kernel source (version: 3.14) ``` struct files_struct { atomic_t count; struct fdtable __rcu *fdt; struct fdtable fdtab; spinlock_t file_lock ____cacheline_aligned_in_smp; int next_fd; unsigned long close_on_exec_init[1]; unsigned long open_fds_init[1]; struct file __rcu * fd_array[NR_OPEN_DEFAULT]; }; ``` I just wonder why `close_on_exec_init` and `open_fds_init` are defined as arrays containing one element, rather than just defined as `unsigned long close_on_exec_init;` and `unsigned long open_fds_init;`.

Original source

Related problems