2005-12-25 16:50:34

by Mateusz Berezecki

[permalink] [raw]
Subject: kernel list / container_of aka list_entry question

Hello list readers,

I have two questions and I'll keep them short

First one is about list_entry definition which is just a wrapper to
container_of with exactly the same arguments (namely, ptr, type, member)
whereas container_of is defined as follows

/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})


My question is why is there a '0' inside a definition?

The second question is why the following code generates errors
during compilation. list.h header file is included.

struct atheros_priv *priv = ieee80211_priv(dev); /* line number 141 */
struct list_head *iterator;


list_for_each(iterator, &priv->rxbuf.list) {
struct ath_buf *bf = list_entry(iterator, (struct ath_buf), list);

/* ... some operations on *bf here ... */
}

and errors are as follows

CC [M] /home/mb/atheros/transmit_receive.o
/home/mb/atheros/transmit_receive.c: In function 'ath_startrecv':
/home/mb/atheros/transmit_receive.c:141: error: syntax error before ')' token
/home/mb/atheros/transmit_receive.c:141: error: '__mptr' undeclared
(first use in this function)
/home/mb/atheros/transmit_receive.c:141: error: (Each undeclared
identifier is reported only once
/home/mb/atheros/transmit_receive.c:141: error: for each function it
appears in.)
/home/mb/atheros/transmit_receive.c:141: error: syntax error before ';' token
/home/mb/atheros/transmit_receive.c:141: error: syntax error before ')' token
/home/mb/atheros/transmit_receive.c:141: error: syntax error before '(' token
/home/mb/atheros/transmit_receive.c:141: error: 'list' undeclared
(first use in this function)
make[2]: *** [/home/mb/atheros/transmit_receive.o] Error 1


I'd appreciate if someone could help me with this problem.

kind regards
Mateusz Berezecki


2005-12-25 17:24:47

by Fawad Lateef

[permalink] [raw]
Subject: Re: kernel list / container_of aka list_entry question

On 12/25/05, Mateusz Berezecki <[email protected]> wrote:
> I have two questions and I'll keep them short
>
> First one is about list_entry definition which is just a wrapper to
> container_of with exactly the same arguments (namely, ptr, type, member)
> whereas container_of is defined as follows
>
<snip>
> #define container_of(ptr, type, member) ({ \
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> (type *)( (char *)__mptr - offsetof(type,member) );})
>
>
> My question is why is there a '0' inside a definition?
>

The Statement ----> const typeof( ((type *)0)->member) *__mptr =
(ptr); is basically declaring a constant pointer of the data-type
exactly same as the member data-type of the type (can be "struct foo"
let say) argument. For this by specifying ((type *)0)->member you
actually telling the compiler that at the address 0 my type (struct
foo) pointer is located and get me the member field of it and then my
typeof you are getting the typeof the member field. If you don't
specify (type *)0 then how you can tell the compiler to get the typeof
member field of the type (struct foo).

I hope you are will be able to get answer with my explanation.


> The second question is why the following code generates errors
> during compilation. list.h header file is included.
>
> struct atheros_priv *priv = ieee80211_priv(dev); /* line number 141 */
> struct list_head *iterator;
>
>
> list_for_each(iterator, &priv->rxbuf.list) {
> struct ath_buf *bf = list_entry(iterator, (struct ath_buf), list);
>
> /* ... some operations on *bf here ... */
> }
>
> and errors are as follows
>
> CC [M] /home/mb/atheros/transmit_receive.o
> /home/mb/atheros/transmit_receive.c: In function 'ath_startrecv':
> /home/mb/atheros/transmit_receive.c:141: error: syntax error before ')' token
> /home/mb/atheros/transmit_receive.c:141: error: '__mptr' undeclared
> (first use in this function)
> /home/mb/atheros/transmit_receive.c:141: error: (Each undeclared
> identifier is reported only once
> /home/mb/atheros/transmit_receive.c:141: error: for each function it
> appears in.)
> /home/mb/atheros/transmit_receive.c:141: error: syntax error before ';' token
> /home/mb/atheros/transmit_receive.c:141: error: syntax error before ')' token
> /home/mb/atheros/transmit_receive.c:141: error: syntax error before '(' token
> /home/mb/atheros/transmit_receive.c:141: error: 'list' undeclared
> (first use in this function)
> make[2]: *** [/home/mb/atheros/transmit_receive.o] Error 1
>
>

I just say that check your header files included, because I think the
.h file containing definition of struct ath_buf is not included and
the list_entry won't able to create __mptr pointer or so !

--
Fawad Lateef

2005-12-25 18:14:16

by Michael Buesch

[permalink] [raw]
Subject: Re: kernel list / container_of aka list_entry question

On Sunday 25 December 2005 18:24, you wrote:
> > The second question is why the following code generates errors
> > during compilation. list.h header file is included.
> >
> > struct atheros_priv *priv = ieee80211_priv(dev); /* line number 141 */
> > struct list_head *iterator;
> >
> >
> > list_for_each(iterator, &priv->rxbuf.list) {
> > struct ath_buf *bf = list_entry(iterator, (struct ath_buf), list);
^ ^
Remove the parenthesis.

--
Greetings Michael.


Attachments:
(No filename) (574.00 B)
(No filename) (189.00 B)
Download all attachments

2005-12-25 18:28:55

by Mateusz Berezecki

[permalink] [raw]
Subject: Re: kernel list / container_of aka list_entry question

On 12/25/05, Michael Buesch <[email protected]> wrote:

> > > list_for_each(iterator, &priv->rxbuf.list) {
> > > struct ath_buf *bf = list_entry(iterator, (struct ath_buf), list);
> ^ ^
> Remove the parenthesis.

yikes. that helped. but it's somewhat weird IMHO... why ((struct foo)
*) wont work?
and it needs to be (struct foo *) ?


kind regards,
Mateusz

2005-12-25 18:30:40

by Mateusz Berezecki

[permalink] [raw]
Subject: Re: kernel list / container_of aka list_entry question

On 12/25/05, Fawad Lateef <[email protected]> wrote:

> I hope you are will be able to get answer with my explanation.

Yes it was helpful. Thank you very much for the explanation.

>
> I just say that check your header files included, because I think the

Headers were ok :-)


regards
Mateusz

2005-12-25 18:56:00

by Fawad Lateef

[permalink] [raw]
Subject: Re: kernel list / container_of aka list_entry question

On 12/25/05, Mateusz Berezecki <[email protected]> wrote:
> On 12/25/05, Michael Buesch <[email protected]> wrote:
>
> > > > list_for_each(iterator, &priv->rxbuf.list) {
> > > > struct ath_buf *bf = list_entry(iterator, (struct ath_buf), list);
> > ^ ^
> > Remove the parenthesis.
>
> yikes. that helped. but it's somewhat weird IMHO... why ((struct foo)
> *) wont work?
> and it needs to be (struct foo *) ?
>

What I can say is that compiler will consider the construct like
(struct foo *) as this (struct foo)* will be making compiler confused
that (struct foo) is type-casting and the * might be for deferencing
the pointer but as * is also in a bracket and wont follow any pointer
thats why compiler is giving error. (CMIIW)

--
Fawad Lateef