为什么这样的结构包含两个只包含一个元素的数组字段?

xml*_*lmx 10 c linux arrays struct idioms

请注意:这个问题不是(struct中的一个元素数组)的重复

以下代码摘自Linux内核源代码(版本: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];
};
Run Code Online (Sandbox Code Playgroud)

我只是想知道为什么close_on_exec_initopen_fds_init被定义为包含一个元素的数组,而不是仅仅定义为unsigned long close_on_exec_init;unsigned long open_fds_init;.

rob*_*off 5

这些字段是一种优化,因此Linux不必为只有BITS_PER_LONG打开文件描述符的典型进程执行尽可能多的分配.

close_on_exec_init字段为分配fdt->close_on_execa时提供初始存储files_struct.(参见dup_fdfs/file.c).

fdt->close_on_exec如果相应的文件描述符设置了"close-on-exec"标志,则设置每个位.因此,fdt->close_on_exec如果进程具有比a中的位数更多的打开文件描述符,则Linux仅需要分配额外的空间unsigned long.

open_fds_init字段为该字段提供相同的功能fdt->open_fds.该fd_array字段为该字段提供相同的功能fdt->fd.(注意,fd_array大小为BITS_PER_LONG.)

close_on_exec_initopen_fds_init领域以前有型struct embedded_fd_set,但被改为裸数组中这个承诺.提交消息不能解释为什么作者选择使用单元素数组而不是裸标量.也许作者(David Howells)只是想避免使用&运算符.


j_r*_*ker 2

我的最佳猜测:这些字段的地址的使用频率比其实际值要高得多。在这种情况下,使它们成为 size-1 数组可以节省&每次需要其地址时的输入,因为在 C 中,在表达式中使用数组名称几乎在所有情况下都完全等同于获取其第一个元素的地址:

int x;
int y[1];

function_that_needs_address_of_int(&x);
function_that_needs_address_of_int(y);
function_that_needs_address_of_int(&y[0]);    // Identical to previous line
Run Code Online (Sandbox Code Playgroud)

(正如其他人在评论中指出的那样,这些字段不可能被用作可变长度数组的黑客,因为有多个字段并且它们不会出现在 的末尾struct。)

[编辑:正如 user3477950 所指出的,数组名称并不总是与其第一个元素的地址相同——在某些上下文中,比如 的参数sizeof,它们意味着不同的东西。(这是我能想到的 C 的唯一上下文;在 C++ 中,将数组名称作为参数传递也可以将模板参数的类型推断为引用类型。)]

  • “在表达式中使用数组的名称完全等同于获取其第一个元素的地址” - 不,它们并不完全等同(想想 `sizeof` 等),最好解释一下数组名称可以在某些情况下衰减为指向其第一个元素的指针。 (3认同)