Назначение является примером использования литералов Compund.Согласно C99 Section # 6.5.2.5 :
Постфиксное выражение, состоящее из имени типа в скобках, за которым следует заключенный в скобки список инициализаторов, представляет собой составной литерал .Он предоставляет неназванный объект, значение которого задается списком инициализаторов.
В более простой версии, согласно Документы GCC: Составные литералы :
Составной литерал выглядит как приведение списка инициализатора агрегата в скобках.Его значение представляет собой объект типа, указанного в приведении, содержащий элементы, указанные в инициализаторе.В отличие от результата приведения, составной литерал является lvalue.ISO C99 и более поздние версии поддерживают составные литералы.В качестве расширения GCC поддерживает составные литералы также в режиме C90 и в C ++, хотя, как объясняется ниже, семантика C ++ несколько отличается.
Простой пример:
struct foo { int x; int y; };
func() {
struct foo var = { .x = 2, .y = 3 };
...
}
В примере вопроса struct file_operations
определено в include / linux / fs.h , а tracing_fops
находится в kernel / trace / trace.c в дереве исходных текстов Linux.
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
...
};
open
, read
, write
являются указателями на функции , которые являются указателями на функцию.После разыменования указателя функции его можно использовать как обычный вызов функции.Структура tracing_fops
имеет тип file_operations
.Значения членов указателя функции присваиваются функциям в том же файле trace.c
с использованием составных литералов.
С составными литералами нам не нужно явно указывать / присваивать все элементы в типе структуры, потому что другие члены установлены в ноль или ноль.Объекты структуры, созданные с использованием составных литералов, могут быть переданы в функции независимо от порядка членов.Параметры функции должны быть одинаковыми для обеих сторон.Например, параметры
int (*open) (struct inode *, struct file *);
такие же, как
int tracing_open(struct inode *inode, struct file *file);
В объектно-ориентированном программировании эта идея несколько похожа на Таблица виртуальных функций.