LINUX.ORG.RU

Из структуры sock в структуру llc_sock

 ,


1

1

Ковыряю ядро Linux. Очередные непонятки. Вот есть в ядре такой файл: /include/net/llc_conn.h , в нём есть функция static inline struct llc_sock *llc_sk(const struct sock *sk). Исходник. Сам текст функции:

static inline struct llc_sock *llc_sk(const struct sock *sk)
{
	return (struct llc_sock *)sk;
}

Насколько я понимаю, тут указатель на некую структуру sock будет переделываться на указатель на структуру llc_sock. Причём начало структуры llc_sock выглядит так:

struct llc_sock {
	/* struct sock must be the first member of llc_sock */
	struct sock	    sk;
	struct sockaddr_llc addr;		/* address sock is bound to */
...
	u32		    copied_seq;		/* head of yet unread data */
...

То есть, внутри структуры llc_sock есть структура sock. Меня интересует следующий вопрос: какое значение будет в copied_seq после подобного приведения? Насколько я могу судить, то значение copied_seq может быть любым, а struct sock sk будет являть собой struct sock sk из аргумента функции. Правильно ли это?


Раз делают такое преобразование, то подразумевается, что входной аргумент является на самом деле указателем на llc_sock. Так что всё там будет инициализированно, если кто-то не передаст неправильный аргумент.

xaizek ★★★★★
()

Если в llc_sk передадут указатель на структуру не совпадающую по layout с struct llc_sock, то обращение к любым полям кроме sk будет UB. Другими словами, это часть механизма type erasure, рассчитывающая на то что ему передадут указатель на полноценный struct llc_sock ранее скастованный к struct sock.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

ему передадут указатель на полноценный struct llc_sock ранее скастованный к struct sock.

Не скастованный, а просто возьмут указатель на первое поле &llc_sock->sk. На самом деле совсем не обязательно было делать его первым, для полей из середины для аналогичного (узнать родительскую структуру по адресу её поля) часто используют макрос с названием containerof, но для первого поля адрес поля просто совпадает с адресом структуры, можно тайпкастить.

firkax ★★★★★
()

это реализация с++ наследования ручками. sock - типа базовый класс для llc_sock. функция есть преобразовоание типа от «базового» класса sock к наследнику. реально указатель должен указывать на обьект типа llc_sock. сам указатель не меняется, просто приводится к тому типу на который реально указывает.

alysnix ★★★
()