LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 09-21-2013, 08:59 AM   #1
songcaidao
LQ Newbie
 
Registered: Sep 2013
Posts: 9

Rep: Reputation: Disabled
container_of:why not "const typeof(*ptr) *__mptr=(ptr);"


Hi,I was reading about the implementation of the kernel's linked list.And I was fascinated by the macro container_of.
Code:
define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
After I figured out every word in the definition,I got another question:
why not replace const typeof( ((type *)0)->member ) *__mptr = (ptr); with "const typeof(*ptr) *__mptr=(ptr);" ?
The second can also check the incompatible initialization and seems more easily to be understood.
 
Old 09-22-2013, 02:21 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
This is not an official answer, but that's how I see it. The de-reference for a 'member' will always point to the right field. The way you propose would probably work if you're sure 'member' is always the first field (with no padding at the beginning of the structure), and it may or may not be true depending on the compiler and platform's ABI.
 
1 members found this post helpful.
Old 09-22-2013, 03:42 PM   #3
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by songcaidao View Post
why not replace const typeof( ((type *)0)->member ) *__mptr = (ptr); with "const typeof(*ptr) *__mptr=(ptr);" ?
I think the intent is to generate an error in case typeof(*(ptr)) is the wrong type.

Quote:
The second can also check the incompatible initialization and seems more easily to be understood.
Why do you think that checks for incompatible initialization?
Code:
const typeof(*ptr) *__mptr=(ptr);
That will compile even if *(ptr) is the wrong type.
Code:
(type *)( (char *)__mptr - offsetof(type,member) )
That will compile even if __mptr is the wrong type.
An advantage of:
Code:
const typeof( ((type *)0)->member ) *__mptr = (ptr);
is that it won't compile if ptr is an incompatible type.

Last edited by johnsfine; 09-22-2013 at 03:53 PM.
 
1 members found this post helpful.
Old 09-22-2013, 10:27 PM   #4
songcaidao
LQ Newbie
 
Registered: Sep 2013
Posts: 9

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
I think the intent is to generate an error in case typeof(*(ptr)) is the wrong type.



Why do you think that checks for incompatible initialization?
Code:
const typeof(*ptr) *__mptr=(ptr);
That will compile even if *(ptr) is the wrong type.
Code:
(type *)( (char *)__mptr - offsetof(type,member) )
That will compile even if __mptr is the wrong type.
An advantage of:
Code:
const typeof( ((type *)0)->member ) *__mptr = (ptr);
is that it won't compile if ptr is an incompatible type.
Thank you!
first of all,i want to replace the kernel's implementation with
Code:
#define container_of(ptr,type,member) ({ \
(type)*((char *)(ptr)-offsetof(type,member));})
.
and then i found it can not check the initialization like this
Code:
int a;
container_of(a,type,member);
.
but the macro what i mentioned in this thread works.and it made me believe the macro can work everywhere.
thank you for your reminding!i found it could not check the wrong type in this kind of initialization:
Code:
struct dog * pdog;
container_of(&pdog,struct dog,list);
thanks again!
 
Old 09-23-2013, 06:24 AM   #5
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by songcaidao View Post
i found it could not check the wrong type in this kind of initialization:
Code:
struct dog * pdog;
container_of(&pdog,struct dog,list);
That isn't a wrong type. It is a wrong value. &pdog has the correct type. It just does not have a value compatible with use of that macro.

A compiler can't check that your code is logically correct.
 
Old 09-23-2013, 07:05 AM   #6
songcaidao
LQ Newbie
 
Registered: Sep 2013
Posts: 9

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
That isn't a wrong type. It is a wrong value. &pdog has the correct type. It just does not have a value compatible with use of that macro.

A compiler can't check that your code is logically correct.
Thanks!I get it.
 
Old 10-26-2013, 08:35 AM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by gschen123 View Post
if typeof(*ptr) isnot the typeof(member), how could you do.
Your question may need a few more words. Anyway I don't want to guess at the meaning of your question.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
PTR question L1nuxn00b703 Linux - Newbie 1 06-26-2012 02:57 AM
[SOLVED] Pointer arithmetic question : *ptr++ or (*ptr)++ theKbStockpiler Programming 8 06-02-2010 11:12 AM
any difference between "const myClass &obj" and "myClass const &obj"? parv Programming 9 01-09-2008 08:58 AM
PTR record OTIM Linux - Server 3 11-22-2007 12:16 PM
PTR problem csdhiman Linux - Server 2 11-18-2007 01:20 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 12:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration