LINUX.ORG.RU

list_for_each


0

1

вот интересно в linux/list.h есть такой код

#define list_for_each(pos, head) \
        for (pos = (head)->next; prefetch(pos->next), pos != (head); \
                pos = pos->next)
если написать такой код
 
struct list_head *head, *pos, **ppos = &pos;
list_for_each(*ppos, head)
{
        //...
}
пишет ошибку из за неправильного приоритета *ppos->next а если так (pos)->next макрос поправить то ок вот как ниже
#define list_for_each(pos, head) \
      for (pos = (head)->next; prefetch((pos)->next), pos != (head); \
                pos = (pos)->next)
то ок ... зачем было запрещать *pos выражение в аргументе макроса ? оно же корректное можно конечно перед вызовом в скобки взять
list_for_each((*ppos), head)
{
        //...
}
но это семантически абсолютно неочевидно



Последнее исправление: osox (всего исправлений: 1)

$ grep -r "list_for_each(" *
arch/arm/kernel/bios32.c:	list_for_each(l, &pci_root_buses) {
arch/ia64/kernel/perfmon.c:	list_for_each(pos, &pfm_buffer_fmt_list) {
arch/ia64/kernel/perfmon.c:	list_for_each(pos, &pfm_buffer_fmt_list) {
arch/s390/appldata/appldata_base.c:	list_for_each(lh, &appldata_ops_list) {
arch/s390/appldata/appldata_base.c:	list_for_each(lh, &appldata_ops_list) {
arch/s390/appldata/appldata_base.c:	list_for_each(lh, &appldata_ops_list) {
arch/s390/appldata/appldata_base.c:	list_for_each(lh, &appldata_ops_list) {
arch/s390/mm/extmem.c:	list_for_each(l, &dcss_list) {
arch/s390/mm/page-states.c:			list_for_each(l, &zone->free_area[order].free_list[t]) {
arch/mips/pmc-sierra/yosemite/ht-irq.c:	list_for_each(devices_link, &(current_bus->devices)) {
arch/frv/mm/mmu-context.c:			list_for_each(_p, &cxn_owners_lru) {
arch/um/drivers/mconsole_kern.c:	list_for_each(ele, &mconsole_devices) {
arch/um/drivers/mconsole_kern.c:		list_for_each(ele, &clients) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, &line->chan_list) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, &list) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/chan_kern.c:	list_for_each(ele, chans) {
arch/um/drivers/net_kern.c:	list_for_each(ele, &devices) {
arch/um/drivers/net_kern.c:	list_for_each(ele, &transports) {
...
...

Как видите, нигде не используется указатель на указатель, как в вашем примере.

Да и в описании макроса написано:

 * @pos:	the &struct list_head to use as a loop cursor.
Т.е. ожидается указатель на структуру.

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

Т.е. ожидается указатель на структуру.

дык а я что передаю ?

list_for_each(*ppos, head)
указатель и передаю

osox
() автор топика
Ответ на: комментарий от osox

>указатель и передаю

Да, вы правы.

Но ведь вы работаете с макросом, а не с функцией.

А макрос просто раскрывается препроцессором, и вместо pos подставляется еще не разыменованный указатель на указатель.

Конечно, было бы правильно обернуть все параметры макроса в круглые скобки во избежания недоразумений, но видимо в ядре это не нужно, т.к. макросу всегда передается указатель на структуру, который разыменовывать не нужно (и соответственно недоразумений со старшинством операций не возникает).

edigaryev ★★★★★
()

вполне себе баг! мелкий, но баг.

xydo ★★
()

Странные списке в ядре. Этот list_for_each всегда пропускает один элемент списка. Не всегда понятно что передавать в list_entry (например список task_struct->children, но в list_entry передается sibling). Вроде бы список циклический, но получается что task_struct->children это какая-то точка входа в список.

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

> Этот list_for_each всегда пропускает один элемент списка

Потому что первый элемент списка не является элементом списка.

получается что task_struct->children это какая-то точка входа в список.


Именно так.

Дело в том, что все элементы, кроме первого, могут быть выделенны kmalloc'ом/kmem_cache_alloc'ом и К°.

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.